if Application.compile_env(:explorer, :chain_type) !== :zksync do
  defmodule Explorer.SmartContract.Solidity.VerifierTest do
    use ExUnit.Case, async: true
    use Explorer.DataCase

    @moduletag timeout: :infinity

    doctest Explorer.SmartContract.Solidity.Verifier

    alias Explorer.Chain.Data
    alias Explorer.SmartContract.Solidity.Verifier
    alias Explorer.Factory

    @optimization_runs 200

    @code_0_4 """
    pragma solidity ^0.4.0;
    contract Incrementer {
        event Incremented(address indexed sender, uint256 newValue);
        uint256 public value;
        address public lastSender;
        constructor(uint256 initialValue) public {
            value = initialValue;
            lastSender = msg.sender;
        }
        function inc(uint256 delta) public {
            value = value + delta;
            lastSender = msg.sender;
        }
    }
    """

    @code_0_5 """
    pragma solidity ^0.5.0;
    contract Incrementer {
        event Incremented(address indexed sender, uint256 newValue);
        uint256 public value;
        address public lastSender;
        constructor(uint256 initialValue) public {
            value = initialValue;
            lastSender = msg.sender;
        }
        function inc(uint256 delta) public {
            value = value + delta;
            lastSender = msg.sender;
        }
    }
    """

    @code_0_6 """
    pragma solidity ^0.6.0;
    contract Incrementer {
        event Incremented(address indexed sender, uint256 newValue);
        uint256 public value;
        address public lastSender;
        constructor(uint256 initialValue) public {
            value = initialValue;
            lastSender = msg.sender;
        }
        function inc(uint256 delta) public {
            value = value + delta;
            lastSender = msg.sender;
        }
    }
    """

    setup do
      configuration = Application.get_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour)
      Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, enabled: false)

      on_exit(fn ->
        Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, configuration)
      end)
    end

    describe "evaluate_authenticity/2" do
      setup do
        {:ok, contract_code_info: Factory.contract_code_info()}
      end

      test "verifies the generated bytecode against bytecode retrieved from the blockchain", %{
        contract_code_info: contract_code_info
      } do
        contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: contract_code_info.tx_input)
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_code_info.source_code,
          "compiler_version" => contract_code_info.version,
          "name" => contract_code_info.name,
          "optimization" => contract_code_info.optimized
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies the generated bytecode with external libraries" do
        contract_data =
          "#{File.cwd!()}/test/support/fixture/smart_contract/contract_with_lib.json"
          |> File.read!()
          |> Jason.decode!()
          |> List.first()

        compiler_version = contract_data["compiler_version"]
        external_libraries = contract_data["external_libraries"]
        name = contract_data["name"]
        optimize = contract_data["optimize"]
        contract = contract_data["contract"]
        expected_bytecode = contract_data["expected_bytecode"]
        tx_input = contract_data["tx_input"]

        contract_address = insert(:contract_address, contract_code: "0x" <> expected_bytecode)

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: "0x" <> tx_input)
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract,
          "compiler_version" => compiler_version,
          "name" => name,
          "optimization" => optimize,
          "external_libraries" => external_libraries
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies smart contract with new `whisper` metadata (bzz0 => bzz1) in solidity 0.5.11" do
        contract_data =
          "#{File.cwd!()}/test/support/fixture/smart_contract/solidity_5.11_new_whisper_metadata.json"
          |> File.read!()
          |> Jason.decode!()

        compiler_version = contract_data["compiler_version"]
        name = contract_data["name"]
        optimize = false
        contract = contract_data["contract"]
        expected_bytecode = contract_data["bytecode"]
        evm_version = contract_data["evm_version"]
        input = contract_data["input"]

        contract_address = insert(:contract_address, contract_code: "0x" <> expected_bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: "0x" <> input
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract,
          "compiler_version" => compiler_version,
          "evm_version" => evm_version,
          "name" => name,
          "optimization" => optimize
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies smart contract and ignores not needed constructor arguments", %{
        contract_code_info: contract_code_info
      } do
        contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)

        constructor_arguments = "0102030405"

        params = %{
          "contract_source_code" => contract_code_info.source_code,
          "compiler_version" => contract_code_info.version,
          "name" => contract_code_info.name,
          "optimization" => contract_code_info.optimized,
          "constructor_arguments" => constructor_arguments
        }

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_code_info.tx_input
        )
        |> with_block(status: :ok)

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "tries to compile with the latest evm version if wrong evm version was provided" do
        bytecode =
          "0x6060604052341561000f57600080fd5b604051602080610223833981016040528080519060200190919050505b8060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505b61019d806100866000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063256fec88146100545780633fa4f245146100a9578063812600df146100d2575b600080fd5b341561005f57600080fd5b6100676100f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156100b457600080fd5b6100bc61011b565b6040518082815260200191505060405180910390f35b34156100dd57600080fd5b6100f36004808035906020019091905050610121565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505600a165627a7a723058201de7017582ff17d45730bc9aedeac5b399399b71b188f42a164609c1b6f7f4760029"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode <> constructor_arguments
        )
        |> with_block(status: :ok)

        code = """
        pragma solidity ^0.4.15;
        contract Incrementer {
            event Incremented(address indexed sender, uint256 newValue);
            uint256 public value;
            address public lastSender;
            function Incrementer(uint256 initialValue) {
                value = initialValue;
                lastSender = msg.sender;
            }
            function inc(uint256 delta) {
                value = value + delta;
                lastSender = msg.sender;
            }
        }
        """

        params = %{
          "contract_source_code" => code,
          "compiler_version" => "v0.4.15+commit.bbb8e64f",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies a library" do
        bytecode =
          "0x610102610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063c2985578146038575b600080fd5b603e60b0565b6040805160208082528351818301528351919283929083019185019080838360005b8381101560765781810151838201526020016060565b50505050905090810190601f16801560a25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080518082019091526003815262666f6f60e81b60208201529056fea265627a7a7231582079c18e1f9cf2812147d15e5d44f16ff748f8b7349d32dc9db50300a3ffbd3a9664736f6c634300050b0032"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: bytecode)
        |> with_block(status: :ok)

        code = """
        pragma solidity 0.5.11;

        library Foo {
            function foo() external pure returns (string memory) {
                return "foo";
            }
        }
        """

        params = %{
          "contract_source_code" => code,
          "compiler_version" => "v0.5.11+commit.c082d0b4",
          "evm_version" => "default",
          "name" => "Foo",
          "optimization" => true
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies smart contract compiled with Solidity 0.5.9 (includes new metadata in bytecode) with constructor args and does not verify with wrong args" do
        path = File.cwd!() <> "/test/support/fixture/smart_contract/solidity_0.5.9_smart_contract.sol"
        contract = File.read!(path)

        wrong_constructor_arguments =
          "00000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000a54657374546f6b656e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006546f6b656e320000000000000000000000000000000000000000000000000000"

        constructor_arguments =
          "0000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000954657374546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005546f6b656e000000000000000000000000000000000000000000000000000000"

        bytecode =
          "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80633177029f116100715780633177029f1461025f57806354fd4d50146102c557806370a082311461034857806395d89b41146103a0578063a9059cbb14610423578063dd62ed3e14610489576100a9565b806306fdde03146100ae578063095ea7b31461013157806318160ddd1461019757806323b872dd146101b5578063313ce5671461023b575b600080fd5b6100b6610501565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561014757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061059f565b604051808215151515815260200191505060405180910390f35b61019f610691565b6040518082815260200191505060405180910390f35b610221600480360360608110156101cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610696565b604051808215151515815260200191505060405180910390f35b61024361090f565b604051808260ff1660ff16815260200191505060405180910390f35b6102ab6004803603604081101561027557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610922565b604051808215151515815260200191505060405180910390f35b6102cd610a14565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561030d5780820151818401526020810190506102f2565b50505050905090810190601f16801561033a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61038a6004803603602081101561035e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ab2565b6040518082815260200191505060405180910390f35b6103a8610afa565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103e85780820151818401526020810190506103cd565b50505050905090810190601f1680156104155780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61046f6004803603604081101561043957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b98565b604051808215151515815260200191505060405180910390f35b6104eb6004803603604081101561049f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cfe565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105975780601f1061056c57610100808354040283529160200191610597565b820191906000526020600020905b81548152906001019060200180831161057a57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b600090565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610762575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b801561076e5750600082115b1561090357816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610908565b600090505b9392505050565b600460009054906101000a900460ff1681565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610aaa5780601f10610a7f57610100808354040283529160200191610aaa565b820191906000526020600020905b815481529060010190602001808311610a8d57829003601f168201915b505050505081565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b905780601f10610b6557610100808354040283529160200191610b90565b820191906000526020600020905b815481529060010190602001808311610b7357829003601f168201915b505050505081565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610be85750600082115b15610cf357816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610cf8565b600090505b92915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509291505056fea265627a7a723058202bede3d06720cdf63e8e43fa1d96f228a476cc899ae007bf684e802f2484ce7664736f6c63430005090032"

        input =
          "0x60806040526040518060400160405280600381526020017f302e3100000000000000000000000000000000000000000000000000000000008152506006908051906020019062000051929190620001e2565b503480156200005f57600080fd5b506040516200105b3803806200105b833981810160405260808110156200008557600080fd5b81019080805190602001909291908051640100000000811115620000a857600080fd5b82810190506020810184811115620000bf57600080fd5b8151856001820283011164010000000082111715620000dd57600080fd5b50509291906020018051906020019092919080516401000000008111156200010457600080fd5b828101905060208101848111156200011b57600080fd5b81518560018202830111640100000000821117156200013957600080fd5b5050929190505050836000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836002819055508260039080519060200190620001a3929190620001e2565b5081600460006101000a81548160ff021916908360ff1602179055508060059080519060200190620001d7929190620001e2565b505050505062000291565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200022557805160ff191683800117855562000256565b8280016001018555821562000256579182015b828111156200025557825182559160200191906001019062000238565b5b50905062000265919062000269565b5090565b6200028e91905b808211156200028a57600081600090555060010162000270565b5090565b90565b610dba80620002a16000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80633177029f116100715780633177029f1461025f57806354fd4d50146102c557806370a082311461034857806395d89b41146103a0578063a9059cbb14610423578063dd62ed3e14610489576100a9565b806306fdde03146100ae578063095ea7b31461013157806318160ddd1461019757806323b872dd146101b5578063313ce5671461023b575b600080fd5b6100b6610501565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561014757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061059f565b604051808215151515815260200191505060405180910390f35b61019f610691565b6040518082815260200191505060405180910390f35b610221600480360360608110156101cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610696565b604051808215151515815260200191505060405180910390f35b61024361090f565b604051808260ff1660ff16815260200191505060405180910390f35b6102ab6004803603604081101561027557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610922565b604051808215151515815260200191505060405180910390f35b6102cd610a14565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561030d5780820151818401526020810190506102f2565b50505050905090810190601f16801561033a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61038a6004803603602081101561035e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ab2565b6040518082815260200191505060405180910390f35b6103a8610afa565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103e85780820151818401526020810190506103cd565b50505050905090810190601f1680156104155780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61046f6004803603604081101561043957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b98565b604051808215151515815260200191505060405180910390f35b6104eb6004803603604081101561049f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cfe565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105975780601f1061056c57610100808354040283529160200191610597565b820191906000526020600020905b81548152906001019060200180831161057a57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b600090565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610762575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b801561076e5750600082115b1561090357816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610908565b600090505b9392505050565b600460009054906101000a900460ff1681565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610aaa5780601f10610a7f57610100808354040283529160200191610aaa565b820191906000526020600020905b815481529060010190602001808311610a8d57829003601f168201915b505050505081565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b905780601f10610b6557610100808354040283529160200191610b90565b820191906000526020600020905b815481529060010190602001808311610b7357829003601f168201915b505050505081565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610be85750600082115b15610cf357816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610cf8565b600090505b92915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509291505056fea265627a7a723058202bede3d06720cdf63e8e43fa1d96f228a476cc899ae007bf684e802f2484ce7664736f6c63430005090032"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: input <> constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract,
          "compiler_version" => "v0.5.9+commit.e560f70d",
          "evm_version" => "petersburg",
          "name" => "TestToken",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil

        contract_address_1 = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address_1.hash,
          input: input <> constructor_arguments
        )
        |> with_block(status: :ok)

        params_1 = %{
          "contract_source_code" => contract,
          "compiler_version" => "v0.5.9+commit.e560f70d",
          "evm_version" => "petersburg",
          "name" => "TestToken",
          "optimization" => false,
          "constructor_arguments" => wrong_constructor_arguments,
          "autodetect_constructor_args" => false
        }

        assert {:error, :constructor_arguments} = Verifier.evaluate_authenticity(contract_address_1.hash, params_1)
      end

      # flaky test
      test "returns error when bytecode doesn't match", %{contract_code_info: contract_code_info} do
        contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: contract_code_info.tx_input)
        |> with_block(status: :ok)

        different_code = "pragma solidity ^0.4.24; contract SimpleStorage {}"

        params = %{
          "contract_source_code" => different_code,
          "compiler_version" => contract_code_info.version,
          "evm_version" => "default",
          "name" => contract_code_info.name,
          "optimization" => contract_code_info.optimized
        }

        response = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert {:error, :generated_bytecode} = response
      end

      # flaky test
      test "returns error when contract has constructor arguments and they were not provided" do
        path = File.cwd!() <> "/test/support/fixture/smart_contract/solidity_0.5.9_smart_contract.sol"
        contract = File.read!(path)

        constructor_arguments = ""

        bytecode =
          "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80633177029f116100715780633177029f1461025f57806354fd4d50146102c557806370a082311461034857806395d89b41146103a0578063a9059cbb14610423578063dd62ed3e14610489576100a9565b806306fdde03146100ae578063095ea7b31461013157806318160ddd1461019757806323b872dd146101b5578063313ce5671461023b575b600080fd5b6100b6610501565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561014757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061059f565b604051808215151515815260200191505060405180910390f35b61019f610691565b6040518082815260200191505060405180910390f35b610221600480360360608110156101cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610696565b604051808215151515815260200191505060405180910390f35b61024361090f565b604051808260ff1660ff16815260200191505060405180910390f35b6102ab6004803603604081101561027557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610922565b604051808215151515815260200191505060405180910390f35b6102cd610a14565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561030d5780820151818401526020810190506102f2565b50505050905090810190601f16801561033a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61038a6004803603602081101561035e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ab2565b6040518082815260200191505060405180910390f35b6103a8610afa565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103e85780820151818401526020810190506103cd565b50505050905090810190601f1680156104155780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61046f6004803603604081101561043957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b98565b604051808215151515815260200191505060405180910390f35b6104eb6004803603604081101561049f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cfe565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105975780601f1061056c57610100808354040283529160200191610597565b820191906000526020600020905b81548152906001019060200180831161057a57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b600090565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610762575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b801561076e5750600082115b1561090357816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610908565b600090505b9392505050565b600460009054906101000a900460ff1681565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610aaa5780601f10610a7f57610100808354040283529160200191610aaa565b820191906000526020600020905b815481529060010190602001808311610a8d57829003601f168201915b505050505081565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b905780601f10610b6557610100808354040283529160200191610b90565b820191906000526020600020905b815481529060010190602001808311610b7357829003601f168201915b505050505081565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610be85750600082115b15610cf357816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610cf8565b600090505b92915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509291505056fea265627a7a72305820fe0ba5210ac95870683c2cb054304b04565703bd16c7d7e956df694c9643c6d264736f6c63430005090032"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode <> constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract,
          "compiler_version" => "v0.5.9+commit.e560f70d",
          "evm_version" => "petersburg",
          "name" => "TestToken",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:error, :generated_bytecode} = Verifier.evaluate_authenticity(contract_address.hash, params)
      end

      test "returns error when there is a compilation problem", %{contract_code_info: contract_code_info} do
        contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)

        params = %{
          "contract_source_code" => "pragma solidity ^0.4.24; contract SimpleStorage { ",
          "compiler_version" => contract_code_info.version,
          "name" => contract_code_info.name,
          "optimization" => contract_code_info.optimized
        }

        assert {:error, :compilation, "Function, variable, struct or modifier declaration expected."} =
                 Verifier.evaluate_authenticity(contract_address.hash, params)
      end
    end

    describe "extract_bytecode_and_metadata_hash/1" do
      test "extracts the bytecode from the hash" do
        code =
          "0x608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a723058203c381c1b48b38d050c54d7ef296ecd411040e19420dfec94772b9c49ae106a0b0029"

        assert %{
                 "metadata_hash_with_length" =>
                   "a165627a7a723058203c381c1b48b38d050c54d7ef296ecd411040e19420dfec94772b9c49ae106a0b0029",
                 "trimmed_bytecode" =>
                   "608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600",
                 "compiler_version" => nil
               } = Verifier.extract_bytecode_and_metadata_hash(code, code)
      end

      test "extracts everything to the left of the swarm hash" do
        contract_creation_code =
          "0x60806040526315c8dd0d60005534801561001857600080fd5b5060405161053e38038061053e8339810160408190526100379161039b565b855161004a906001906020890190610056565b505050505050506104f1565b828054828255906000526020600020908101928215610091579160200282015b82811115610091578251825591602001919060010190610076565b5061009d9291506100a1565b5090565b5b8082111561009d57600081556001016100a2565b60006001600160401b038311156100cf576100cf6104db565b60206100e3601f8501601f19168201610488565b91508382528484840111156100f757600080fd5b60005b84811015610113578381015183820183015281016100fa565b848111156101245760008286850101525b50509392505050565b600082601f83011261013d578081fd5b8151602061015261014d836104b8565b610488565b80838252828201915082860187848660051b8901011115610171578586fd5b855b858110156101a35781516001600160a01b0381168114610191578788fd5b84529284019290840190600101610173565b5090979650505050505050565b600082601f8301126101c0578081fd5b815160206101d061014d836104b8565b80838252828201915082860187848660051b89010111156101ef578586fd5b855b858110156101a35781518015158114610208578788fd5b845292840192908401906001016101f1565b600082601f83011261022a578081fd5b8151602061023a61014d836104b8565b80838252828201915082860187848660051b8901011115610259578586fd5b855b858110156101a35781516001600160401b03811115610278578788fd5b8801603f81018a13610288578788fd5b6102998a87830151604084016100b6565b855250928401929084019060010161025b565b600082601f8301126102bc578081fd5b815160206102cc61014d836104b8565b80838252828201915082860187848660051b89010111156102eb578586fd5b855b858110156101a3578151845292840192908401906001016102ed565b600082601f830112610319578081fd5b8151602061032961014d836104b8565b80838252828201915082860187848660051b8901011115610348578586fd5b855b858110156101a35781516001600160401b03811115610367578788fd5b8801603f81018a13610377578788fd5b6103888a87830151604084016100b6565b855250928401929084019060010161034a565b60008060008060008060c087890312156103b3578182fd5b86516001600160401b03808211156103c9578384fd5b6103d58a838b016102ac565b975060208901519150808211156103ea578384fd5b6103f68a838b0161012d565b9650604089015191508082111561040b578384fd5b6104178a838b016102ac565b9550606089015191508082111561042c578384fd5b6104388a838b016101b0565b9450608089015191508082111561044d578384fd5b6104598a838b0161021a565b935060a089015191508082111561046e578283fd5b5061047b89828a01610309565b9150509295509295509295565b604051601f8201601f191681016001600160401b03811182821017156104b0576104b06104db565b604052919050565b60006001600160401b038211156104d1576104d16104db565b5060051b60200190565b634e487b7160e01b600052604160045260246000fd5b603f806104ff6000396000f3fe6080604052600080fdfea26469706673582212209864ab97aa6a0d2c5cc0828f7fbe63df8fb5e90c758d49371edb3184bcc8239664736f6c6343000804003300000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000756b5b30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000bb36c792b9b45aaf8b848a1392b0d6559202729e000000000000000000000000bb36c792b9b45aaf8b848a1392b0d6559202729e000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0000000000000000000000000000000000000000000000000000000000000006ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f0000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000371776500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003657771000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097177657177657177650000000000000000000000000000000000000000000000"

        deployed_bytecode =
          "0x6080604052600080fdfea26469706673582212209864ab97aa6a0d2c5cc0828f7fbe63df8fb5e90c758d49371edb3184bcc8239664736f6c63430008040033"

        assert %{
                 "metadata_hash_with_length" =>
                   "a26469706673582212209864ab97aa6a0d2c5cc0828f7fbe63df8fb5e90c758d49371edb3184bcc8239664736f6c63430008040033",
                 "trimmed_bytecode" =>
                   "60806040526315c8dd0d60005534801561001857600080fd5b5060405161053e38038061053e8339810160408190526100379161039b565b855161004a906001906020890190610056565b505050505050506104f1565b828054828255906000526020600020908101928215610091579160200282015b82811115610091578251825591602001919060010190610076565b5061009d9291506100a1565b5090565b5b8082111561009d57600081556001016100a2565b60006001600160401b038311156100cf576100cf6104db565b60206100e3601f8501601f19168201610488565b91508382528484840111156100f757600080fd5b60005b84811015610113578381015183820183015281016100fa565b848111156101245760008286850101525b50509392505050565b600082601f83011261013d578081fd5b8151602061015261014d836104b8565b610488565b80838252828201915082860187848660051b8901011115610171578586fd5b855b858110156101a35781516001600160a01b0381168114610191578788fd5b84529284019290840190600101610173565b5090979650505050505050565b600082601f8301126101c0578081fd5b815160206101d061014d836104b8565b80838252828201915082860187848660051b89010111156101ef578586fd5b855b858110156101a35781518015158114610208578788fd5b845292840192908401906001016101f1565b600082601f83011261022a578081fd5b8151602061023a61014d836104b8565b80838252828201915082860187848660051b8901011115610259578586fd5b855b858110156101a35781516001600160401b03811115610278578788fd5b8801603f81018a13610288578788fd5b6102998a87830151604084016100b6565b855250928401929084019060010161025b565b600082601f8301126102bc578081fd5b815160206102cc61014d836104b8565b80838252828201915082860187848660051b89010111156102eb578586fd5b855b858110156101a3578151845292840192908401906001016102ed565b600082601f830112610319578081fd5b8151602061032961014d836104b8565b80838252828201915082860187848660051b8901011115610348578586fd5b855b858110156101a35781516001600160401b03811115610367578788fd5b8801603f81018a13610377578788fd5b6103888a87830151604084016100b6565b855250928401929084019060010161034a565b60008060008060008060c087890312156103b3578182fd5b86516001600160401b03808211156103c9578384fd5b6103d58a838b016102ac565b975060208901519150808211156103ea578384fd5b6103f68a838b0161012d565b9650604089015191508082111561040b578384fd5b6104178a838b016102ac565b9550606089015191508082111561042c578384fd5b6104388a838b016101b0565b9450608089015191508082111561044d578384fd5b6104598a838b0161021a565b935060a089015191508082111561046e578283fd5b5061047b89828a01610309565b9150509295509295509295565b604051601f8201601f191681016001600160401b03811182821017156104b0576104b06104db565b604052919050565b60006001600160401b038211156104d1576104d16104db565b5060051b60200190565b634e487b7160e01b600052604160045260246000fd5b603f806104ff6000396000f3fe6080604052600080fdfe00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000756b5b30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000bb36c792b9b45aaf8b848a1392b0d6559202729e000000000000000000000000bb36c792b9b45aaf8b848a1392b0d6559202729e000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0000000000000000000000000000000000000000000000000000000000000006ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f0000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000371776500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003657771000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097177657177657177650000000000000000000000000000000000000000000000",
                 "compiler_version" => %CBOR.Tag{tag: :bytes, value: <<0, 8, 4>>}
               } = Verifier.extract_bytecode_and_metadata_hash(contract_creation_code, deployed_bytecode)
      end

      # https://solidity.readthedocs.io/en/v0.6.6/contracts.html?highlight=immutable#constant-and-immutable-state-variables
      test "verifies smart-contract with `immutable` assignment" do
        bytecode =
          "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063fb49908514602d575b600080fd5b605060048036036020811015604157600080fd5b50356001600160a01b03166064565b604080519115158252519081900360200190f35b7f0000000000000000000000000000000000000000000000056b3977a93ae7c2006001600160a01b038216311191905056fea2646970667358221220b4fbf35809f2d1b85699a897ebb75d00c8c26b29b72decc53db18ddbd853352164736f6c63430006070033"

        tx_input =
          "0x60e06040523360601b60c05234801561001757600080fd5b5060405161013f38038061013f8339818101604052604081101561003a57600080fd5b50805160209091015160808290526001600160a01b03163160a081905260c05160601c60cc6100736000395080606652505060cc6000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063fb49908514602d575b600080fd5b605060048036036020811015604157600080fd5b50356001600160a01b03166064565b604080519115158252519081900360200190f35b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038216311191905056fea2646970667358221220b4fbf35809f2d1b85699a897ebb75d00c8c26b29b72decc53db18ddbd853352164736f6c63430006070033000000000000000000000000000000000000000000000000000000000000000100000000000000000000000023602745048d3b8d0a7f953ad444da4cd237ac83"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: tx_input)
        |> with_block(status: :ok)

        code = """
        pragma solidity >0.6.4 <0.7.0;

        contract C {
            uint constant X = 32**22 + 8;
            string constant TEXT = "abc";
            bytes32 constant MY_HASH = keccak256("abc");
            uint immutable decimals;
            uint immutable maxBalance;
            address immutable owner = msg.sender;

            constructor(uint _decimals, address _reference) public {
                decimals = _decimals;
                // Assignments to immutables can even access the environment.
                maxBalance = _reference.balance;
            }

            function isBalanceTooHigh(address _other) public view returns (bool) {
                return _other.balance > maxBalance;
            }
        }
        """

        constructor_arguments =
          "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000023602745048d3b8d0a7f953ad444da4cd237ac83"

        params = %{
          "contract_source_code" => code,
          "compiler_version" => "v0.6.7+commit.b8d736ae",
          "evm_version" => "default",
          "name" => "C",
          "optimization" => true,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies smart-contract created from another contract" do
        path = File.cwd!() <> "/test/support/fixture/smart_contract/contract_from_factory.sol"
        contract = File.read!(path)

        constructor_arguments = "4e1477bdc40fc2458bf646f96f269502658277779fdf0f4080fe798a2d45bc37"

        bytecode =
          "0x608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638052474d81146043575b600080fd5b348015604e57600080fd5b5060556067565b60408051918252519081900360200190f35b600054815600a165627a7a72305820a1a0ec90e133c3064fab0ae82aa02a020224ea39d2b5421b6788f800bdde02f60029"

        init =
          "0x608060405234801561001057600080fd5b506040516020806100cc83398101604052516000556099806100336000396000f300608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638052474d81146043575b600080fd5b348015604e57600080fd5b5060556067565b60408051918252519081900360200190f35b600054815600a165627a7a72305820a1a0ec90e133c3064fab0ae82aa02a020224ea39d2b5421b6788f800bdde02f600294e1477bdc40fc2458bf646f96f269502658277779fdf0f4080fe798a2d45bc37"

        contract_address = insert(:contract_address, contract_code: bytecode)

        transaction_success_details = [
          status: :ok
        ]

        transaction =
          :transaction
          |> insert()
          |> with_block(transaction_success_details)

        :internal_transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          init: init,
          type: "create",
          created_contract_code: bytecode,
          input: nil,
          transaction_hash: transaction.hash,
          index: 0,
          block_hash: transaction.block_hash,
          block_index: 0
        )

        params = %{
          "contract_source_code" => contract,
          "compiler_version" => "v0.4.26+commit.4563c3fc",
          "evm_version" => "default",
          "name" => "ContractFromFactory",
          "optimization" => true,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verifies smart-contract created from another contract using successful tx" do
        path = File.cwd!() <> "/test/support/fixture/smart_contract/contract_from_factory.sol"
        contract = File.read!(path)

        constructor_arguments = "4e1477bdc40fc2458bf646f96f269502658277779fdf0f4080fe798a2d45bc37"

        bytecode =
          "0x608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638052474d81146043575b600080fd5b348015604e57600080fd5b5060556067565b60408051918252519081900360200190f35b600054815600a165627a7a72305820a1a0ec90e133c3064fab0ae82aa02a020224ea39d2b5421b6788f800bdde02f60029"

        init =
          "0x608060405234801561001057600080fd5b506040516020806100cc83398101604052516000556099806100336000396000f300608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638052474d81146043575b600080fd5b348015604e57600080fd5b5060556067565b60408051918252519081900360200190f35b600054815600a165627a7a72305820a1a0ec90e133c3064fab0ae82aa02a020224ea39d2b5421b6788f800bdde02f600294e1477bdc40fc2458bf646f96f269502658277779fdf0f4080fe798a2d45bc37"

        contract_address = insert(:contract_address, contract_code: bytecode)

        transaction_success_details = [
          status: :ok
        ]

        transaction_success =
          :transaction
          |> insert()
          |> with_block(transaction_success_details)

        transaction_failure_details = [
          status: :error
        ]

        transaction_failure =
          :transaction
          |> insert()
          |> with_block(transaction_failure_details)

        :internal_transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          init: init,
          type: "create",
          created_contract_code: bytecode,
          input: nil,
          transaction_hash: transaction_success.hash,
          index: 0,
          block_hash: transaction_success.block_hash,
          block_index: 0
        )

        :internal_transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          init: init,
          type: "create",
          created_contract_code: bytecode,
          input: nil,
          transaction_hash: transaction_failure.hash,
          index: 0,
          block_hash: transaction_failure.block_hash,
          block_index: 0
        )

        params = %{
          "contract_source_code" => contract,
          "compiler_version" => "v0.4.26+commit.4563c3fc",
          "evm_version" => "default",
          "name" => "ContractFromFactory",
          "optimization" => true,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end
    end

    describe "compiler version tests" do
      # flaky test
      test "verification is failed if wrong version of compiler" do
        bytecode_0_5_10 =
          "0x608060405234801561001057600080fd5b506040516102453803806102458339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101a98061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72305820fb47165501c50aae8ccb0394b15f4302606e0ba55eb6d59fe12eca19ba494d5e64736f6c634300050a0032"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_5_10)
        bytecode_constructor_arguments = "#{bytecode_0_5_10}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_5,
          "compiler_version" => "v0.5.11+commit.c082d0b4",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        response = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert {:error, :compiler_version} = response
      end

      test "verification is successful if proper version of compiler" do
        bytecode_0_5_10 =
          "0x608060405234801561001057600080fd5b506040516102453803806102458339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101a98061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72305820fb47165501c50aae8ccb0394b15f4302606e0ba55eb6d59fe12eca19ba494d5e64736f6c634300050a0032"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_5_10)
        bytecode_constructor_arguments = "#{bytecode_0_5_10}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_5,
          "compiler_version" => "v0.5.10+commit.5a6ea5b1",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end
    end

    describe "verification with nightly builds" do
      test "verification is successful if proper nightly version of compiler ~0.4" do
        bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2 =
          "0x608060405234801561001057600080fd5b5060405160208061023d833981018060405281019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101b28061008b6000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063256fec881461005c5780633fa4f245146100b3578063812600df146100de575b600080fd5b34801561006857600080fd5b5061007161010b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610131565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610137565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a723058202d622d653be0a507f7ac0bc89d8934ccdbaf5e127abd603c3864a462149885070029"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2)
        bytecode_constructor_arguments = "#{bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_4,
          "compiler_version" => "v0.4.24-nightly.2018.4.26+commit.ef2111a2",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verification is successful if proper nightly version of compiler ~0.5.10" do
        bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4 =
          "0x608060405234801561001057600080fd5b5060405161026a38038061026a8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101ce8061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a723058208d4e3fa9b2179a8384e617e388dde334be1b44e7b11b42ab964ab1050e7cedca64736f6c637827302e352e31302d6e696768746c792e323031392e362e342b636f6d6d69742e39356536623265340057"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4)
        bytecode_constructor_arguments = "#{bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_5,
          "compiler_version" => "v0.5.10-nightly.2019.6.4+commit.95e6b2e4",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verification is successful if proper nightly version of compiler ~0.5.11" do
        bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753 =
          "0x608060405234801561001057600080fd5b5060405161026b38038061026b8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101cf8061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72305820f7420b8c3b16d83ce728d8c279f0f887c4dcd7bfcd38c484acc9cdb82fde785764736f6c637828302e352e31312d6e696768746c792e323031392e362e32352b636f6d6d69742e31636338343735330058"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753)
        bytecode_constructor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_5,
          "compiler_version" => "v0.5.11-nightly.2019.6.25+commit.1cc84753",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verification is successful if proper nightly version of compiler ~0.5.14" do
        bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88 =
          "0x608060405234801561001057600080fd5b5060405161026c38038061026c8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101d08061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820ec5a7ce04b1c2f97a3d3e61ae1b5cb06585e81c504542fd9668a8ead654da72764736f6c637829302e352e31342d6e696768746c792e323031392e31322e31302b636f6d6d69742e34356161376138380059"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88)
        bytecode_constructor_arguments = "#{bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_5,
          "compiler_version" => "v0.5.14-nightly.2019.12.10+commit.45aa7a88",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verification is successful if proper nightly version of compiler ~0.6.0" do
        bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8 =
          "0x608060405234801561001057600080fd5b5060405161026a38038061026a8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101ce8061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea264697066735822122029b5dde5889a195ed02cebb1a638ae3754be34464b9a2bc8b48b6286636031fb64736f6c637826302e362e312d6e696768746c792e323032302e312e322b636f6d6d69742e64303832623962380057"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8)
        bytecode_constructor_arguments = "#{bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_6,
          "compiler_version" => "v0.6.1-nightly.2020.1.2+commit.d082b9b8",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "verification is failed if wrong nightly version of compiler ~0.5.11" do
        bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753 =
          "0x608060405234801561001057600080fd5b5060405161026b38038061026b8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101cf8061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72305820f5be0e6763c440be759726643bdd4b03370e9f1b58fd803ab18b0b4f2aa58b7664736f6c637828302e352e31312d6e696768746c792e323031392e362e32352b636f6d6d69742e31636338343735330058"

        constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
        contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753)
        bytecode_constructor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}"

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: bytecode_constructor_arguments
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => @code_0_5,
          "compiler_version" => "v0.5.11-nightly.2019.8.10+commit.f5f2bbb2",
          "evm_version" => "homestead",
          "name" => "Incrementer",
          "optimization" => false,
          "constructor_arguments" => constructor_arguments
        }

        response = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert {:error, :compiler_version} = response
      end
    end

    describe "regression tests for https://github.com/blockscout/blockscout/pull/5166" do
      test "issue 5114" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_5114.sol"
          |> File.read!()

        bytecode =
          "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ed565b610118565b61005b610093366004610707565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ed565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b03161415610159576101548161040b565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b606061029183836040518060600160405280602781526020016108016027913961045f565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b600061035061053a565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b583610562565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103f65750805b156101d557610405838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610434610379565b604080516001600160a01b03928316815291841660208301520160405180910390a161016181610611565b606061046a84610298565b6104c55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104e09190610785565b600060405180830381855af49150503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b509150915061053082828661069d565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61056b81610298565b6105cd5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381166106765760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105f0565b606083156106ac575081610291565b8251156106bc5782518084602001fd5b8160405162461bcd60e51b815260040161033891906107a1565b80356001600160a01b038116811461029d57600080fd5b6000602082840312156106fe578081fd5b610291826106d6565b60008060006040848603121561071b578182fd5b610724846106d6565b9250602084013567ffffffffffffffff80821115610740578384fd5b818601915086601f830112610753578384fd5b813581811115610761578485fd5b876020828501011115610772578485fd5b6020830194508093505050509250925092565b600082516107978184602087016107d4565b9190910192915050565b60006020825282518060208401526107c08160408501602087016107d4565b601f01601f19169190910160400192915050565b60005b838110156107ef5781810151838201526020016107d7565b83811115610405575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122016ea36e15be10f9560025e0ec9401e2e9110cb5ec41d110b4a0e391838c1f19b64736f6c63430008020033"

        contract_creation_code =
          "0x608060405260405162000f4038038062000f408339810160408190526200002691620004d4565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd62000603565b60008051602062000ef9833981519152146200008157634e487b7160e01b600052600160045260246000fd5b6200008f82826000620000ff565b50620000bf905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610462000603565b60008051602062000ed983398151915214620000eb57634e487b7160e01b600052600160045260246000fd5b620000f68262000170565b5050506200066c565b6200010a83620001cb565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806200014c5750805b156200016b576200016983836200029360201b6200026c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200019b620002c2565b604080516001600160a01b03928316815291841660208301520160405180910390a1620001c881620002fb565b50565b620001e1816200038b60201b620002981760201c565b620002495760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b806200027260008051602062000ef983398151915260001b6200039560201b620002141760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060620002bb838360405180606001604052806027815260200162000f196027913962000398565b9392505050565b6000620002ec60008051602062000ed983398151915260001b6200039560201b620002141760201c565b546001600160a01b0316905090565b6001600160a01b038116620003625760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840162000240565b806200027260008051602062000ed983398151915260001b6200039560201b620002141760201c565b803b15155b919050565b90565b6060620003a5846200038b565b620004025760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b0316856040516200041f9190620005b0565b600060405180830381855af49150503d80600081146200045c576040519150601f19603f3d011682016040523d82523d6000602084013e62000461565b606091505b509092509050620004748282866200047e565b9695505050505050565b606083156200048f575081620002bb565b825115620004a05782518084602001fd5b8160405162461bcd60e51b8152600401620002409190620005ce565b80516001600160a01b03811681146200039057600080fd5b600080600060608486031215620004e9578283fd5b620004f484620004bc565b92506200050460208501620004bc565b60408501519092506001600160401b038082111562000521578283fd5b818601915086601f83011262000535578283fd5b8151818111156200054a576200054a62000656565b604051601f8201601f19908116603f0116810190838211818310171562000575576200057562000656565b816040528281528960208487010111156200058e578586fd5b620005a183602083016020880162000627565b80955050505050509250925092565b60008251620005c481846020870162000627565b9190910192915050565b6000602082528251806020840152620005ef81604085016020870162000627565b601f01601f19169190910160400192915050565b6000828210156200062257634e487b7160e01b81526011600452602481fd5b500390565b60005b83811015620006445781810151838201526020016200062a565b83811115620001695750506000910152565b634e487b7160e01b600052604160045260246000fd5b61085d806200067c6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ed565b610118565b61005b610093366004610707565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ed565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b03161415610159576101548161040b565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b606061029183836040518060600160405280602781526020016108016027913961045f565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b600061035061053a565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b583610562565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103f65750805b156101d557610405838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610434610379565b604080516001600160a01b03928316815291841660208301520160405180910390a161016181610611565b606061046a84610298565b6104c55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104e09190610785565b600060405180830381855af49150503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b509150915061053082828661069d565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61056b81610298565b6105cd5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381166106765760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105f0565b606083156106ac575081610291565b8251156106bc5782518084602001fd5b8160405162461bcd60e51b815260040161033891906107a1565b80356001600160a01b038116811461029d57600080fd5b6000602082840312156106fe578081fd5b610291826106d6565b60008060006040848603121561071b578182fd5b610724846106d6565b9250602084013567ffffffffffffffff80821115610740578384fd5b818601915086601f830112610753578384fd5b813581811115610761578485fd5b876020828501011115610772578485fd5b6020830194508093505050509250925092565b600082516107978184602087016107d4565b9190910192915050565b60006020825282518060208401526107c08160408501602087016107d4565b601f01601f19169190910160400192915050565b60005b838110156107ef5781810151838201526020016107d7565b83811115610405575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122016ea36e15be10f9560025e0ec9401e2e9110cb5ec41d110b4a0e391838c1f19b64736f6c63430008020033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c65640000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.2+commit.661d1103",
          "evm_version" => "default",
          "name" => "TransparentUpgradeableProxy",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "0000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end

      test "issue 5127" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_5127.sol"
          |> File.read!()

        bytecode =
          "0x60806040523480156200001157600080fd5b5060405162001bfc38038062001bfc8339810160408190526200003491620002d6565b6040805180820182526009808252682ca2a9902a37b5b2b760b91b6020808401918252845180860190955260038086526259455360e81b91860191909152600080546001600160a01b03808c16610100026001600160a81b03199092169190911790915560018054828b166001600160a01b03199182161790915560028054928a169290911691909117905585905582519293926012928992899289928992620000de9262000213565b508551620000f490600a90602089019062000213565b5050600b805460ff90951660ff199095169490941790935550620001209350339250889150506200012b565b505050505062000398565b6001600160a01b038216620001865760405162461bcd60e51b815260206004820152601f60248201527f4b415032303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b80600860008282546200019a919062000334565b90915550506001600160a01b03821660009081526006602052604081208054839290620001c990849062000334565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b82805462000221906200035b565b90600052602060002090601f01602090048101928262000245576000855562000290565b82601f106200026057805160ff191683800117855562000290565b8280016001018555821562000290579182015b828111156200029057825182559160200191906001019062000273565b506200029e929150620002a2565b5090565b5b808211156200029e5760008155600101620002a3565b80516001600160a01b0381168114620002d157600080fd5b919050565b600080600080600060a08688031215620002ef57600080fd5b855194506200030160208701620002b9565b93506200031160408701620002b9565b92506200032160608701620002b9565b9150608086015190509295509295909350565b600082198211156200035657634e487b7160e01b600052601160045260246000fd5b500190565b600181811c908216806200037057607f821691505b602082108114156200039257634e487b7160e01b600052602260045260246000fd5b50919050565b61185480620003a86000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638456cb591161010f578063bddae40e116100a2578063dd62ed3e11610071578063dd62ed3e14610420578063de9c2a6b14610459578063f71c559c14610466578063f9f92be41461047957600080fd5b8063bddae40e146103cf578063c2f92192146103e2578063d864e740146103f5578063da72c1e81461040d57600080fd5b80639cfe42da116100de5780639cfe42da1461038e578063a1d5ec4b146103a1578063a457c2d7146103a9578063a9059cbb146103bc57600080fd5b80638456cb59146103405780638e39103c1461034857806390d6b45f1461035b57806395d89b411461038657600080fd5b8063394b652b1161018757806359e026f71161015657806359e026f7146102e65780635c975abb146102f9578063704b6c021461030457806370a082311461031757600080fd5b8063394b652b146102a357806339509351146102b85780633f4ba83a146102cb578063483a83df146102d357600080fd5b806318160ddd116101c357806318160ddd146102515780631ae878d31461026857806323b872dd14610271578063313ce5671461028457600080fd5b806306fdde03146101ea578063095ea7b3146102085780631714d7f31461022b575b600080fd5b6101f261049c565b6040516101ff9190611574565b60405180910390f35b61021b6102163660046115aa565b61052a565b60405190151581526020016101ff565b6101f2604051806040016040528060078152602001667975656d6d616960c81b81525081565b61025a60085481565b6040519081526020016101ff565b61025a60035481565b61021b61027f3660046115d4565b610540565b600b546102919060ff1681565b60405160ff90911681526020016101ff565b6102b66102b1366004611610565b610651565b005b61021b6102c63660046115aa565b61068c565b6102b66106c8565b6102b66102e1366004611629565b610701565b61021b6102f43660046115d4565b610739565b60005460ff1661021b565b6102b6610312366004611629565b61094f565b61025a610325366004611629565b6001600160a01b031660009081526006602052604090205490565b6102b6610a1b565b6102b6610356366004611629565b610a52565b60025461036e906001600160a01b031681565b6040516001600160a01b0390911681526020016101ff565b6101f2610a8a565b6102b661039c366004611629565b610a97565b6102b6610acf565b61021b6103b73660046115aa565b610b06565b61021b6103ca3660046115aa565b610b95565b6102b66103dd366004611629565b610bf4565b60015461036e906001600160a01b031681565b60005461036e9061010090046001600160a01b031681565b61021b61041b3660046115d4565b610c2c565b61025a61042e366004611644565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b60045461021b9060ff1681565b61021b6104743660046115d4565b610ddb565b61021b610487366004611629565b60056020526000908152604090205460ff1681565b600980546104a990611677565b80601f01602080910402602001604051908101604052809291908181526020018280546104d590611677565b80156105225780601f106104f757610100808354040283529160200191610522565b820191906000526020600020905b81548152906001019060200180831161050557829003601f168201915b505050505081565b6000610537338484610ede565b50600192915050565b6000805460ff161561056d5760405162461bcd60e51b8152600401610564906116b2565b60405180910390fd5b6001600160a01b038416600090815260056020526040902054849060ff16156105a85760405162461bcd60e51b8152600401610564906116cd565b6105b3858585611002565b6001600160a01b0385166000908152600760209081526040808320338452909152902054838110156106385760405162461bcd60e51b815260206004820152602860248201527f4b415032303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610564565b6106458633868403610ede565b50600195945050505050565b60005461010090046001600160a01b031633146106805760405162461bcd60e51b815260040161056490611704565b610689816111d1565b50565b3360008181526007602090815260408083206001600160a01b038716845290915281205490916105379185906106c3908690611751565b610ede565b60005461010090046001600160a01b031633146106f75760405162461bcd60e51b815260040161056490611704565b6106ff611217565b565b60005461010090046001600160a01b031633146107305760405162461bcd60e51b815260040161056490611704565b61068981611298565b6000805460ff161561075d5760405162461bcd60e51b8152600401610564906116b2565b60015460408051808201825260078152667975656d6d616960c81b602082015290516302b98ccf60e41b81526001600160a01b0390921691632b98ccf0916107aa91339190600401611769565b602060405180830381865afa1580156107c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107eb9190611795565b6108075760405162461bcd60e51b8152600401610564906117b7565b6003546002546040516306f19a8d60e21b81526001600160a01b03878116600483015290911690631bc66a3490602401602060405180830381865afa158015610854573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087891906117ee565b101580156108f657506003546002546040516306f19a8d60e21b81526001600160a01b03868116600483015290911690631bc66a34906024015b602060405180830381865afa1580156108cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f391906117ee565b10155b61093a5760405162461bcd60e51b81526020600482015260156024820152744f6e6c7920696e7465726e616c20707572706f736560581b6044820152606401610564565b610945848484611002565b5060019392505050565b60015460408051808201825260078152667975656d6d616960c81b602082015290516302b98ccf60e41b81526001600160a01b0390921691632b98ccf09161099c91339190600401611769565b602060405180830381865afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190611795565b6109f95760405162461bcd60e51b8152600401610564906117b7565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60005461010090046001600160a01b03163314610a4a5760405162461bcd60e51b815260040161056490611704565b6106ff6112f2565b60005461010090046001600160a01b03163314610a815760405162461bcd60e51b815260040161056490611704565b6106898161134a565b600a80546104a990611677565b60005461010090046001600160a01b03163314610ac65760405162461bcd60e51b815260040161056490611704565b61068981611400565b60005461010090046001600160a01b03163314610afe5760405162461bcd60e51b815260040161056490611704565b6106ff61148a565b3360009081526007602090815260408083206001600160a01b038616845290915281205482811015610b885760405162461bcd60e51b815260206004820152602560248201527f4b415032303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610564565b6109453385858403610ede565b6000805460ff1615610bb95760405162461bcd60e51b8152600401610564906116b2565b3360008181526005602052604090205460ff1615610be95760405162461bcd60e51b8152600401610564906116cd565b610945338585611002565b60005461010090046001600160a01b03163314610c235760405162461bcd60e51b815260040161056490611704565b610689816114c2565b6000805461010090046001600160a01b03163314610c5c5760405162461bcd60e51b815260040161056490611704565b6001600160a01b038416600090815260066020526040902054821115610cd25760405162461bcd60e51b815260206004820152602560248201527f4b415032303a207472616e7366657220616d6f756e74206578636565642062616044820152646c616e636560d81b6064820152608401610564565b6001600160a01b038316610d285760405162461bcd60e51b815260206004820152601f60248201527f4b415032303a207472616e7366657220746f207a65726f2061646472657373006044820152606401610564565b6001600160a01b03841660009081526006602052604081208054849290610d50908490611807565b90915550506001600160a01b03831660009081526006602052604081208054849290610d7d908490611751565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610dc991815260200190565b60405180910390a35060019392505050565b6000805460ff1615610dff5760405162461bcd60e51b8152600401610564906116b2565b60015460408051808201825260078152667975656d6d616960c81b602082015290516302b98ccf60e41b81526001600160a01b0390921691632b98ccf091610e4c91339190600401611769565b602060405180830381865afa158015610e69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8d9190611795565b610ea95760405162461bcd60e51b8152600401610564906117b7565b6003546002546040516306f19a8d60e21b81526001600160a01b03878116600483015290911690631bc66a34906024016108b2565b6001600160a01b038316610f405760405162461bcd60e51b8152602060048201526024808201527f4b415032303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610564565b6001600160a01b038216610fa15760405162461bcd60e51b815260206004820152602260248201527f4b415032303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610564565b6001600160a01b0383811660008181526007602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166110665760405162461bcd60e51b815260206004820152602560248201527f4b415032303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610564565b6001600160a01b0382166110c85760405162461bcd60e51b815260206004820152602360248201527f4b415032303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610564565b6001600160a01b038316600090815260066020526040902054818110156111405760405162461bcd60e51b815260206004820152602660248201527f4b415032303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610564565b6001600160a01b03808516600090815260066020526040808220858503905591851681529081208054849290611177908490611751565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111c391815260200190565b60405180910390a350505050565b600380549082905560408051828152602081018490527f4bb7c3aa2e207c70c9f2b8b0d81e076d62b704e041cdedb61959edd1814912f491015b60405180910390a15050565b60005460ff1661124e5760405162461bcd60e51b815260206004820152600260248201526104e560f41b6044820152606401610564565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600280546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f192570e0851c3af9ff6a477c94534e97444b3893085cf6ac37fb7e7ec335f01e910161120b565b60005460ff16156113155760405162461bcd60e51b8152600401610564906116b2565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861127b3390565b6001600160a01b038116600090815260056020526040902054819060ff166113b45760405162461bcd60e51b815260206004820152601b60248201527f41646472657373206973206e6f7420696e20626c61636b6c69737400000000006044820152606401610564565b6001600160a01b038216600081815260056020526040808220805460ff19169055513392917f6690dc53a3b1d37db94233f7c004408862ea909761dc5760b0e925276754f87591a35050565b6001600160a01b038116600090815260056020526040902054819060ff161561143b5760405162461bcd60e51b8152600401610564906116cd565b6001600160a01b038216600081815260056020526040808220805460ff19166001179055513392917fef674dcdab521405fef2bf4b5d2c6a6434e3ab02bc5a94fb89dd035704b83b0991a35050565b6004805460ff191660011790556040517fa5881517cf4ae3e7f6bcd00c68314e59f3ce78b5606d1b08253addc3c957e43b90600090a1565b60008054610100600160a81b0319166101006001600160a01b0384811682810293909317938490556040805193845291909304909216602082015282917f129aa2e3e7b369511a5c100a66e80b6c6231b4e60460799e7c1ed36e14121568910161120b565b6000815180845260005b8181101561154d57602081850181015186830182015201611531565b8181111561155f576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006115876020830184611527565b9392505050565b80356001600160a01b03811681146115a557600080fd5b919050565b600080604083850312156115bd57600080fd5b6115c68361158e565b946020939093013593505050565b6000806000606084860312156115e957600080fd5b6115f28461158e565b92506116006020850161158e565b9150604084013590509250925092565b60006020828403121561162257600080fd5b5035919050565b60006020828403121561163b57600080fd5b6115878261158e565b6000806040838503121561165757600080fd5b6116608361158e565b915061166e6020840161158e565b90509250929050565b600181811c9082168061168b57607f821691505b602082108114156116ac57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600190820152600560fc1b604082015260600190565b60208082526017908201527f4164647265737320697320696e20626c61636b6c697374000000000000000000604082015260600190565b60208082526019908201527f52657374726963746564206f6e6c7920636f6d6d697474656500000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156117645761176461173b565b500190565b6001600160a01b038316815260406020820181905260009061178d90830184611527565b949350505050565b6000602082840312156117a757600080fd5b8151801515811461158757600080fd5b6020808252601b908201527f52657374726963746564206f6e6c792073757065722061646d696e0000000000604082015260600190565b60006020828403121561180057600080fd5b5051919050565b6000828210156118195761181961173b565b50039056fea2646970667358221220f9aa231f0e2c136b376cc26c179eea8f7aae62c23797e6e17b4ca4462f9ad1af64736f6c634300080b0033"

        contract_creation_code =
          "0x60806040523480156200001157600080fd5b5060405162001bfc38038062001bfc8339810160408190526200003491620002d6565b6040805180820182526009808252682ca2a9902a37b5b2b760b91b6020808401918252845180860190955260038086526259455360e81b91860191909152600080546001600160a01b03808c16610100026001600160a81b03199092169190911790915560018054828b166001600160a01b03199182161790915560028054928a169290911691909117905585905582519293926012928992899289928992620000de9262000213565b508551620000f490600a90602089019062000213565b5050600b805460ff90951660ff199095169490941790935550620001209350339250889150506200012b565b505050505062000398565b6001600160a01b038216620001865760405162461bcd60e51b815260206004820152601f60248201527f4b415032303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b80600860008282546200019a919062000334565b90915550506001600160a01b03821660009081526006602052604081208054839290620001c990849062000334565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b82805462000221906200035b565b90600052602060002090601f01602090048101928262000245576000855562000290565b82601f106200026057805160ff191683800117855562000290565b8280016001018555821562000290579182015b828111156200029057825182559160200191906001019062000273565b506200029e929150620002a2565b5090565b5b808211156200029e5760008155600101620002a3565b80516001600160a01b0381168114620002d157600080fd5b919050565b600080600080600060a08688031215620002ef57600080fd5b855194506200030160208701620002b9565b93506200031160408701620002b9565b92506200032160608701620002b9565b9150608086015190509295509295909350565b600082198211156200035657634e487b7160e01b600052601160045260246000fd5b500190565b600181811c908216806200037057607f821691505b602082108114156200039257634e487b7160e01b600052602260045260246000fd5b50919050565b61185480620003a86000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638456cb591161010f578063bddae40e116100a2578063dd62ed3e11610071578063dd62ed3e14610420578063de9c2a6b14610459578063f71c559c14610466578063f9f92be41461047957600080fd5b8063bddae40e146103cf578063c2f92192146103e2578063d864e740146103f5578063da72c1e81461040d57600080fd5b80639cfe42da116100de5780639cfe42da1461038e578063a1d5ec4b146103a1578063a457c2d7146103a9578063a9059cbb146103bc57600080fd5b80638456cb59146103405780638e39103c1461034857806390d6b45f1461035b57806395d89b411461038657600080fd5b8063394b652b1161018757806359e026f71161015657806359e026f7146102e65780635c975abb146102f9578063704b6c021461030457806370a082311461031757600080fd5b8063394b652b146102a357806339509351146102b85780633f4ba83a146102cb578063483a83df146102d357600080fd5b806318160ddd116101c357806318160ddd146102515780631ae878d31461026857806323b872dd14610271578063313ce5671461028457600080fd5b806306fdde03146101ea578063095ea7b3146102085780631714d7f31461022b575b600080fd5b6101f261049c565b6040516101ff9190611574565b60405180910390f35b61021b6102163660046115aa565b61052a565b60405190151581526020016101ff565b6101f2604051806040016040528060078152602001667975656d6d616960c81b81525081565b61025a60085481565b6040519081526020016101ff565b61025a60035481565b61021b61027f3660046115d4565b610540565b600b546102919060ff1681565b60405160ff90911681526020016101ff565b6102b66102b1366004611610565b610651565b005b61021b6102c63660046115aa565b61068c565b6102b66106c8565b6102b66102e1366004611629565b610701565b61021b6102f43660046115d4565b610739565b60005460ff1661021b565b6102b6610312366004611629565b61094f565b61025a610325366004611629565b6001600160a01b031660009081526006602052604090205490565b6102b6610a1b565b6102b6610356366004611629565b610a52565b60025461036e906001600160a01b031681565b6040516001600160a01b0390911681526020016101ff565b6101f2610a8a565b6102b661039c366004611629565b610a97565b6102b6610acf565b61021b6103b73660046115aa565b610b06565b61021b6103ca3660046115aa565b610b95565b6102b66103dd366004611629565b610bf4565b60015461036e906001600160a01b031681565b60005461036e9061010090046001600160a01b031681565b61021b61041b3660046115d4565b610c2c565b61025a61042e366004611644565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b60045461021b9060ff1681565b61021b6104743660046115d4565b610ddb565b61021b610487366004611629565b60056020526000908152604090205460ff1681565b600980546104a990611677565b80601f01602080910402602001604051908101604052809291908181526020018280546104d590611677565b80156105225780601f106104f757610100808354040283529160200191610522565b820191906000526020600020905b81548152906001019060200180831161050557829003601f168201915b505050505081565b6000610537338484610ede565b50600192915050565b6000805460ff161561056d5760405162461bcd60e51b8152600401610564906116b2565b60405180910390fd5b6001600160a01b038416600090815260056020526040902054849060ff16156105a85760405162461bcd60e51b8152600401610564906116cd565b6105b3858585611002565b6001600160a01b0385166000908152600760209081526040808320338452909152902054838110156106385760405162461bcd60e51b815260206004820152602860248201527f4b415032303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610564565b6106458633868403610ede565b50600195945050505050565b60005461010090046001600160a01b031633146106805760405162461bcd60e51b815260040161056490611704565b610689816111d1565b50565b3360008181526007602090815260408083206001600160a01b038716845290915281205490916105379185906106c3908690611751565b610ede565b60005461010090046001600160a01b031633146106f75760405162461bcd60e51b815260040161056490611704565b6106ff611217565b565b60005461010090046001600160a01b031633146107305760405162461bcd60e51b815260040161056490611704565b61068981611298565b6000805460ff161561075d5760405162461bcd60e51b8152600401610564906116b2565b60015460408051808201825260078152667975656d6d616960c81b602082015290516302b98ccf60e41b81526001600160a01b0390921691632b98ccf0916107aa91339190600401611769565b602060405180830381865afa1580156107c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107eb9190611795565b6108075760405162461bcd60e51b8152600401610564906117b7565b6003546002546040516306f19a8d60e21b81526001600160a01b03878116600483015290911690631bc66a3490602401602060405180830381865afa158015610854573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087891906117ee565b101580156108f657506003546002546040516306f19a8d60e21b81526001600160a01b03868116600483015290911690631bc66a34906024015b602060405180830381865afa1580156108cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f391906117ee565b10155b61093a5760405162461bcd60e51b81526020600482015260156024820152744f6e6c7920696e7465726e616c20707572706f736560581b6044820152606401610564565b610945848484611002565b5060019392505050565b60015460408051808201825260078152667975656d6d616960c81b602082015290516302b98ccf60e41b81526001600160a01b0390921691632b98ccf09161099c91339190600401611769565b602060405180830381865afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190611795565b6109f95760405162461bcd60e51b8152600401610564906117b7565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60005461010090046001600160a01b03163314610a4a5760405162461bcd60e51b815260040161056490611704565b6106ff6112f2565b60005461010090046001600160a01b03163314610a815760405162461bcd60e51b815260040161056490611704565b6106898161134a565b600a80546104a990611677565b60005461010090046001600160a01b03163314610ac65760405162461bcd60e51b815260040161056490611704565b61068981611400565b60005461010090046001600160a01b03163314610afe5760405162461bcd60e51b815260040161056490611704565b6106ff61148a565b3360009081526007602090815260408083206001600160a01b038616845290915281205482811015610b885760405162461bcd60e51b815260206004820152602560248201527f4b415032303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610564565b6109453385858403610ede565b6000805460ff1615610bb95760405162461bcd60e51b8152600401610564906116b2565b3360008181526005602052604090205460ff1615610be95760405162461bcd60e51b8152600401610564906116cd565b610945338585611002565b60005461010090046001600160a01b03163314610c235760405162461bcd60e51b815260040161056490611704565b610689816114c2565b6000805461010090046001600160a01b03163314610c5c5760405162461bcd60e51b815260040161056490611704565b6001600160a01b038416600090815260066020526040902054821115610cd25760405162461bcd60e51b815260206004820152602560248201527f4b415032303a207472616e7366657220616d6f756e74206578636565642062616044820152646c616e636560d81b6064820152608401610564565b6001600160a01b038316610d285760405162461bcd60e51b815260206004820152601f60248201527f4b415032303a207472616e7366657220746f207a65726f2061646472657373006044820152606401610564565b6001600160a01b03841660009081526006602052604081208054849290610d50908490611807565b90915550506001600160a01b03831660009081526006602052604081208054849290610d7d908490611751565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610dc991815260200190565b60405180910390a35060019392505050565b6000805460ff1615610dff5760405162461bcd60e51b8152600401610564906116b2565b60015460408051808201825260078152667975656d6d616960c81b602082015290516302b98ccf60e41b81526001600160a01b0390921691632b98ccf091610e4c91339190600401611769565b602060405180830381865afa158015610e69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8d9190611795565b610ea95760405162461bcd60e51b8152600401610564906117b7565b6003546002546040516306f19a8d60e21b81526001600160a01b03878116600483015290911690631bc66a34906024016108b2565b6001600160a01b038316610f405760405162461bcd60e51b8152602060048201526024808201527f4b415032303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610564565b6001600160a01b038216610fa15760405162461bcd60e51b815260206004820152602260248201527f4b415032303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610564565b6001600160a01b0383811660008181526007602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166110665760405162461bcd60e51b815260206004820152602560248201527f4b415032303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610564565b6001600160a01b0382166110c85760405162461bcd60e51b815260206004820152602360248201527f4b415032303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610564565b6001600160a01b038316600090815260066020526040902054818110156111405760405162461bcd60e51b815260206004820152602660248201527f4b415032303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610564565b6001600160a01b03808516600090815260066020526040808220858503905591851681529081208054849290611177908490611751565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111c391815260200190565b60405180910390a350505050565b600380549082905560408051828152602081018490527f4bb7c3aa2e207c70c9f2b8b0d81e076d62b704e041cdedb61959edd1814912f491015b60405180910390a15050565b60005460ff1661124e5760405162461bcd60e51b815260206004820152600260248201526104e560f41b6044820152606401610564565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600280546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f192570e0851c3af9ff6a477c94534e97444b3893085cf6ac37fb7e7ec335f01e910161120b565b60005460ff16156113155760405162461bcd60e51b8152600401610564906116b2565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861127b3390565b6001600160a01b038116600090815260056020526040902054819060ff166113b45760405162461bcd60e51b815260206004820152601b60248201527f41646472657373206973206e6f7420696e20626c61636b6c69737400000000006044820152606401610564565b6001600160a01b038216600081815260056020526040808220805460ff19169055513392917f6690dc53a3b1d37db94233f7c004408862ea909761dc5760b0e925276754f87591a35050565b6001600160a01b038116600090815260056020526040902054819060ff161561143b5760405162461bcd60e51b8152600401610564906116cd565b6001600160a01b038216600081815260056020526040808220805460ff19166001179055513392917fef674dcdab521405fef2bf4b5d2c6a6434e3ab02bc5a94fb89dd035704b83b0991a35050565b6004805460ff191660011790556040517fa5881517cf4ae3e7f6bcd00c68314e59f3ce78b5606d1b08253addc3c957e43b90600090a1565b60008054610100600160a81b0319166101006001600160a01b0384811682810293909317938490556040805193845291909304909216602082015282917f129aa2e3e7b369511a5c100a66e80b6c6231b4e60460799e7c1ed36e14121568910161120b565b6000815180845260005b8181101561154d57602081850181015186830182015201611531565b8181111561155f576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006115876020830184611527565b9392505050565b80356001600160a01b03811681146115a557600080fd5b919050565b600080604083850312156115bd57600080fd5b6115c68361158e565b946020939093013593505050565b6000806000606084860312156115e957600080fd5b6115f28461158e565b92506116006020850161158e565b9150604084013590509250925092565b60006020828403121561162257600080fd5b5035919050565b60006020828403121561163b57600080fd5b6115878261158e565b6000806040838503121561165757600080fd5b6116608361158e565b915061166e6020840161158e565b90509250929050565b600181811c9082168061168b57607f821691505b602082108114156116ac57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600190820152600560fc1b604082015260600190565b60208082526017908201527f4164647265737320697320696e20626c61636b6c697374000000000000000000604082015260600190565b60208082526019908201527f52657374726963746564206f6e6c7920636f6d6d697474656500000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156117645761176461173b565b500190565b6001600160a01b038316815260406020820181905260009061178d90830184611527565b949350505050565b6000602082840312156117a757600080fd5b8151801515811461158757600080fd5b6020808252601b908201527f52657374726963746564206f6e6c792073757065722061646d696e0000000000604082015260600190565b60006020828403121561180057600080fd5b5051919050565b6000828210156118195761181961173b565b50039056fea2646970667358221220f9aa231f0e2c136b376cc26c179eea8f7aae62c23797e6e17b4ca4462f9ad1af64736f6c634300080b0033000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000073d8f731ec0d3945d807a904bf93954b82b0d594000000000000000000000000c5333c0d3cf6fc8f84f3ccb0d5a73dbda2eceb500000000000000000000000002c8abd9c61d4e973ca8db5545c54c90e44a2445c0000000000000000000000000000000000000000000000000000000000000004"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.11+commit.d7f03943",
          "evm_version" => "default",
          "name" => "YESToken",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000073d8f731ec0d3945d807a904bf93954b82b0d594000000000000000000000000c5333c0d3cf6fc8f84f3ccb0d5a73dbda2eceb500000000000000000000000002c8abd9c61d4e973ca8db5545c54c90e44a2445c0000000000000000000000000000000000000000000000000000000000000004"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end

      test "issue 3082" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_3082.sol"
          |> File.read!()

        bytecode =
          "0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638d3ce69d1161010f578063b2cec8ea116100a2578063cbecb28811610071578063cbecb2881461050a578063f049f33414610512578063f2fde38b14610532578063fc0c546a14610558576101e5565b8063b2cec8ea146104a2578063b99ef521146104c2578063bac883ef146104e2578063bd4b2be914610502576101e5565b8063983c44d6116100de578063983c44d6146103b75780639972444f146103bf578063a3df582a146103df578063a4c0ed36146103e7576101e5565b80638d3ce69d146103635780638d3df3461461036b5780638da5cb5b1461038b5780638f32d59b146103af576101e5565b8063392e53cd11610187578063622c5e4511610156578063622c5e451461032b578063715018a6146103335780637af7c0401461033b5780638129fc1c1461035b576101e5565b8063392e53cd146102b757806359791d6d146102bf5780635f26622f146102df578063604f21771461030b576101e5565b80630f10e06f116101c35780630f10e06f146102695780632755731e14610289578063375a4cab14610291578063381a4113146102af576101e5565b8063014a969a146101ea578063047fc9aa1461021e57806304a3922014610238575b600080fd5b61020a6004803603602081101561020057600080fd5b503560ff16610560565b604080519115158252519081900360200190f35b610226610575565b60408051918252519081900360200190f35b6102676004803603604081101561024e57600080fd5b50803560ff1690602001356001600160a01b0316610584565b005b6102266004803603602081101561027f57600080fd5b503560ff166106d0565b6102266106e2565b6102996106e8565b6040805160ff9092168252519081900360200190f35b61020a6106ed565b61020a6106f6565b610226600480360360208110156102d557600080fd5b503560ff16610704565b610267600480360360408110156102f557600080fd5b506001600160a01b038135169060200135610716565b6102266004803603602081101561032157600080fd5b503560ff16610fc4565b610299610fd6565b610267610fdb565b61020a6004803603602081101561035157600080fd5b503560ff16611073565b610267611088565b6102996111de565b6102266004803603602081101561038157600080fd5b503560ff166111e3565b6103936111f5565b604080516001600160a01b039092168252519081900360200190f35b61020a611204565b610299611215565b610393600480360360208110156103d557600080fd5b503560ff1661121a565b610226611235565b61020a600480360360608110156103fd57600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561042d57600080fd5b82018360208201111561043f57600080fd5b8035906020019184600183028401116401000000008311171561046157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061123b945050505050565b610226600480360360208110156104b857600080fd5b503560ff16611274565b610226600480360360208110156104d857600080fd5b503560ff16611286565b610267600480360360208110156104f857600080fd5b503560ff16611298565b610299611652565b610299611657565b6102266004803603602081101561052857600080fd5b503560ff1661165c565b6102676004803603602081101561054857600080fd5b50356001600160a01b031661166e565b6103936116d3565b600b6020526000908152604090205460ff1681565b6a070fe2cd68c25ff4f0000081565b60ff821660011480610599575060ff82166005145b6105d7576040805162461bcd60e51b815260206004820152600a6024820152691ddc9bdb99c81c1bdbdb60b21b604482015290519081900360640190fd5b60ff82166000908152600260205260409020546001600160a01b03163314610637576040805162461bcd60e51b815260206004820152600e60248201526d1b9bdd08185d5d1a1bdc9a5e995960921b604482015290519081900360640190fd5b610640816116e2565b60ff82166000818152600260209081526040918290205482516001600160a01b0391821681529085169181019190915281517f09a67390cbf7986a6bb0fcb44307b4844ba258bca3f38599d2b344824df4ba1d929181900390910190a260ff91909116600090815260026020526040902080546001600160a01b0319166001600160a01b03909216919091179055565b60056020526000908152604090205481565b600d5481565b600581565b600e5460ff1681565b600e54610100900460ff1681565b60086020526000908152604090205481565b61071e611204565b61076f576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600e5460ff16156107c7576040805162461bcd60e51b815260206004820152601760248201527f616c7265616479207072652d696e697469616c697a6564000000000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b038481169190911791829055604080516370a0823160e01b81523060048201529051600093909216916370a0823191602480820192602092909190829003018186803b15801561082b57600080fd5b505afa15801561083f573d6000803e3d6000fd5b505050506040513d602081101561085557600080fd5b505190506a070fe2cd68c25ff4f0000081146108b1576040805162461bcd60e51b815260206004820152601660248201527577726f6e6720636f6e74726163742062616c616e636560501b604482015290519081900360640190fd5b6108b961172f565b600d55600e805460ff191660011790556003600090815260026020527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c3546040805163189acdbd60e31b81526001600160a01b0387811660048301529151919092169263c4d66de8926024808201939182900301818387803b15801561093e57600080fd5b505af1158015610952573d6000803e3d6000fd5b50506004600081815260026020527fee60d0579bcffd98e668647d59fec1ff86a7fb340ce572e844f234ae73a6918f546040805163189acdbd60e31b81526001600160a01b038a811695820195909552905193909116945063c4d66de893506024808201939182900301818387803b1580156109cd57600080fd5b505af11580156109e1573d6000803e3d6000fd5b5050600360008181526020919091527fcbc4e5fb02c3d1de23a9f1e014b4d2ee5aeaea9505df5e855c9210bf472495af54909250610a3a9150606490610a2e90601963ffffffff61173316565b9063ffffffff61179516565b600154600260009081527f679795a0195a1b76cdebb7c51d74e058aee92919b8c3389af86ef24535e8a28c54600360209081527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d546040805163238a3fe160e01b81526001600160a01b039485166004820152602481019290925251959650919093169363238a3fe19360448084019491938390030190829087803b158015610ae257600080fd5b505af1158015610af6573d6000803e3d6000fd5b505050506040513d6020811015610b0c57600080fd5b505060015460036000908152600260209081527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c3546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018790529051919094169363a9059cbb9360448083019493928390030190829087803b158015610b9157600080fd5b505af1158015610ba5573d6000803e3d6000fd5b505050506040513d6020811015610bbb57600080fd5b50506006600090815260036020527fc69056f16cbaa3c616b828e333ab7d3a32310765507f8f58359e99ebb7a885f354610bfb908563ffffffff6117ff16565b60015460066000908152600260209081527f59dd4b18488d12f51eda69757a0ed42a2010c14b564330cc74a06895e60c077b546040805163238a3fe160e01b81526001600160a01b03928316600482015260248101879052905195965093169363238a3fe193604480820194918390030190829087803b158015610c7e57600080fd5b505af1158015610c92573d6000803e3d6000fd5b505050506040513d6020811015610ca857600080fd5b50508315610d35576001546040805163238a3fe160e01b81526000600482018190526024820188905291516001600160a01b039093169263238a3fe192604480840193602093929083900390910190829087803b158015610d0857600080fd5b505af1158015610d1c573d6000803e3d6000fd5b505050506040513d6020811015610d3257600080fd5b50505b60026000527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d5460046020527f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a754610d929163ffffffff6117ff16565b60046020527f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a75560036000527f2e174c10e159ea99b867ce3205125c24a42d128804e4070ed6fcc8cc98166aa054610df0908363ffffffff6117ff16565b7f2e174c10e159ea99b867ce3205125c24a42d128804e4070ed6fcc8cc98166aa05560066000527fc69056f16cbaa3c616b828e333ab7d3a32310765507f8f58359e99ebb7a885f35460046020527fc59312466997bb42aaaf719ece141047820e6b34531e1670dc1852a453648f0f54610e6f9163ffffffff6117ff16565b6006600052600460209081527fc59312466997bb42aaaf719ece141047820e6b34531e1670dc1852a453648f0f91909155604080516001600160a01b0388168152339281019290925280517f20e0b9d27e138a83ff1b3f687932144f5e913aa93855ac36c2611ec1dfae704e9281900390910190a160026000819052600360209081527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d546040805191825233928201929092528151600080516020611b49833981519152929181900390910190a2604080518381523360208201528151600392600080516020611b49833981519152928290030190a2604080518281523360208201528151600692600080516020611b49833981519152928290030190a28315610fbd57604080518581523360208201528151600092600080516020611b49833981519152928290030190a25b5050505050565b60036020526000908152604090205481565b600481565b610fe3611204565b611034576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152600f60248201526e1b9bdd081a5b5c1b195b595b9d1959608a1b604482015290519081900360640190fd5b600a6020526000908152604090205460ff1681565b600e5460ff166110d5576040805162461bcd60e51b81526020600482015260136024820152721b9bdd081c1c994b5a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b600e54610100900460ff1615611128576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b6276a700611146600d5461113a61172f565b9063ffffffff6117ff16565b101561118f57611154611204565b61118f5760405162461bcd60e51b8152600401808060200182810382526027815260200180611b226027913960400191505060405180910390fd5b61119761172f565b600c55600e805461ff0019166101001790556040805133815290517f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e69181900360200190a1565b600381565b60066020526000908152604090205481565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b600181565b6002602052600090815260409020546001600160a01b031681565b600c5481565b600060405162461bcd60e51b815260040180806020018281038252602e815260200180611bb0602e913960400191505060405180910390fd5b60096020526000908152604090205481565b60046020526000908152604090205481565b600e54610100900460ff166112e6576040805162461bcd60e51b815260206004820152600f60248201526e1b9bdd081a5b9a5d1a585b1a5e9959608a1b604482015290519081900360640190fd5b60ff8116600090815260056020526040902054600c54829161130e919063ffffffff61185c16565b61131661172f565b10158015611336575060ff8082166000908152600b602052604090205416155b6113715760405162461bcd60e51b8152600401808060200182810382526029815260200180611bde6029913960400191505060405180910390fd5b60ff821660031480611386575060ff82166004145b80611394575060ff82166001145b806113a2575060ff82166005145b6113e0576040805162461bcd60e51b815260206004820152600a6024820152691ddc9bdb99c81c1bdbdb60b21b604482015290519081900360640190fd5b60ff8083166000908152600a6020526040812054909116611426575060ff8216600090815260096020908152604080832054600a909252909120805460ff191660011790555b6000611431846118b6565b60ff85166000908152600860205260409020549091506114689061145b908363ffffffff61173316565b839063ffffffff61185c16565b9150600082116114bf576040805162461bcd60e51b815260206004820152601960248201527f6e6f20696e7374616c6c6d656e747320617661696c61626c6500000000000000604482015290519081900360640190fd5b60006114cc8584846119a0565b90506114de838263ffffffff61185c16565b925060ff8516600314806114f5575060ff85166004145b156115905760015460ff8616600090815260026020908152604080832054815163a9059cbb60e01b81526001600160a01b03918216600482015260248101899052915194169363a9059cbb93604480840194938390030190829087803b15801561155e57600080fd5b505af1158015611572573d6000803e3d6000fd5b505050506040513d602081101561158857600080fd5b506116219050565b60015460ff8616600090815260026020908152604080832054815163238a3fe160e01b81526001600160a01b03918216600482015260248101899052915194169363238a3fe193604480840194938390030190829087803b1580156115f457600080fd5b505af1158015611608573d6000803e3d6000fd5b505050506040513d602081101561161e57600080fd5b50505b60408051848152336020820152815160ff881692600080516020611b49833981519152928290030190a25050505050565b600681565b600281565b60076020526000908152604090205481565b611676611204565b6116c7576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6116d081611a5d565b50565b6001546001600160a01b031681565b6001600160a01b0381166116d0576040805162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b604482015290519081900360640190fd5b4290565b6000826117425750600061178f565b8282028284828161174f57fe5b041461178c5760405162461bcd60e51b8152600401808060200182810382526021815260200180611b8f6021913960400191505060405180910390fd5b90505b92915050565b60008082116117eb576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816117f657fe5b04949350505050565b600082821115611856576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008282018381101561178c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60ff811660009081526007602052604081205481906118de906201518063ffffffff61173316565b60ff8416600090815260056020526040812054600c54929350909161191a91849161190e9163ffffffff61185c16565b9063ffffffff61185c16565b905061192f62015180610a2e8361113a61172f565b60ff851660009081526006602090815260408083205460079092529091205491945090611962908563ffffffff61185c16565b11156119995760ff84166000908152600760209081526040808320546006909252909120546119969163ffffffff6117ff16565b92505b5050919050565b60ff831660009081526004602052604081205481906119c5908563ffffffff6117ff16565b60ff86166000908152600460209081526040808320939093556007905220546119f4908463ffffffff61185c16565b60ff861660009081526007602081815260408084208590556006825290922054915211611a555760ff851660009081526004602052604090205415611a4c575060ff8416600090815260046020526040812080549190555b611a5585611afd565b949350505050565b6001600160a01b038116611aa25760405162461bcd60e51b8152600401808060200182810382526026815260200180611b696026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60ff166000908152600b60205260409020805460ff19166001179055565b3b15159056fe666f72206e6f77206f6e6c79206f776e65722063616e2063616c6c2074686973206d6574686f64a8b65b82b2ff2a955e75c1bfa6a0e92aafb764156295da77a0a4c714f3895c724f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7773656e64696e6720746f6b656e7320746f207468697320636f6e7472616374206973206e6f7420616c6c6f776564696e7374616c6c6d656e747320617265206e6f742061637469766520666f72207468697320706f6f6ca265627a7a723058208fc7fe0d6f40178495c4e655627ac8a6bc837eb89686042a07161f078a2ea04464736f6c634300050a0032"

        contract_creation_code =
          "0x6080604052600e805461ffff191690553480156200001c57600080fd5b5060405162002ac338038062002ac3833981810160405260c08110156200004257600080fd5b50805160208201516040808401516060850151608086015160a090960151600080546001600160a01b031916331780825594519697959693959294929391926001600160a01b0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3620000cf846001600160a01b031662000aa160201b62001b1b1760201c565b8015620000f65750620000f6836001600160a01b031662000aa160201b62001b1b1760201c565b6200016257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f74206120636f6e7472616374206164647265737300000000000000000000604482015290519081900360640190fd5b62000176866001600160e01b0362000aa716565b6200018a856001600160e01b0362000aa716565b6200019e826001600160e01b0362000aa716565b620001b2816001600160e01b0362000aa716565b7fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e080546001600160a01b03199081166001600160a01b03898116919091179092557f679795a0195a1b76cdebb7c51d74e058aee92919b8c3389af86ef24535e8a28c805482168884161790557f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c380548216878416179081905560008051602062002a42833981519152805483168785161790557fb98b78633099fa36ed8b8680c4f8092689e1e04080eb9cbb077ca38a14d7e384805483168685161790557f59dd4b18488d12f51eda69757a0ed42a2010c14b564330cc74a06895e60c077b8054909216848416179091556a034f086f3b33b684000000600080516020620029e2833981519152556954b40b1f852bda000000600080516020620029c283398151915255600360005260026020908152604080517f5fd6632000000000000000000000000000000000000000000000000000000000815290519290931692635fd663209260048083019392829003018186803b1580156200035257600080fd5b505afa15801562000367573d6000803e3d6000fd5b505050506040513d60208110156200037e57600080fd5b505160008051602062002aa383398151915255600460008190526002602090815260008051602062002a4283398151915254604080517f5fd6632000000000000000000000000000000000000000000000000000000000815290516001600160a01b0390921693635fd6632093828201939092909190829003018186803b1580156200040957600080fd5b505afa1580156200041e573d6000803e3d6000fd5b505050506040513d60208110156200043557600080fd5b50516003602090815260008051602062002a2283398151915282905569940785b073a9e904000060008051602062002a8383398151915281905569ace68dbebd988d50000060008051602062002a0283398151915281905560008051602062002aa383398151915254600080516020620029c2833981519152546001600052600080516020620029e2833981519152546a070fe2cd68c25ff4f00000966200050e969495620004fa95909486949293859391928492906200185c62000b20821b17901c565b62000b2060201b6200185c1790919060201c565b146200057b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726f6e672073756d206f6620706f6f6c73207374616b657300000000000000604482015290519081900360640190fd5b600080516020620029e2833981519152547fabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe05819055600080516020620029c2833981519152547f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a75560008051602062002aa3833981519152547f2e174c10e159ea99b867ce3205125c24a42d128804e4070ed6fcc8cc98166aa05560008051602062002a22833981519152547f1a1e6821cde7d0159c0d293177871e09677b4e42307c7db3ba94f8648a5a050f5560008051602062002a83833981519152547f04cde762ef08b6b6c5ded8e8c4c0b3f4e5c9ad7342c88fcc93681b4588b73f055560008051602062002a02833981519152547fc59312466997bb42aaaf719ece141047820e6b34531e1670dc1852a453648f0f55600160005260036020908152620006ef91606491620006db91906014906200173362000b9e821b17901c565b62000c1660201b620017951790919060201c565b7f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a365560036000819052602090815260008051602062002aa3833981519152546200074d91606491620006db91600a906200173362000b9e821b17901c565b7fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e75560046000526003602090815260008051602062002a2283398151915254620007ab91606491620006db916014906200173362000b9e821b17901c565b7f8dc18c4ccfd75f5c815b63770fa542fd953e8fef7e0e44bbdd4913470ce7e9cb5560056000526003602090815260008051602062002a83833981519152546200080991606491620006db916014906200173362000b9e821b17901c565b7f74b05292d1d4b2b48b65261b07099d24244bcb069f138d9a6bfdcf776becac4c556301baf8007f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b556224ea007fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc055626ebe007f3eec716f11ba9e820c81ca75eb978ffb45831ef8b7a53e5e422c26008e1ca6d58190557f458b30c2d72bfd2c6317304a4594ecbafe5f729d3111b65fdc3a33bd48e5432d5560066020526101507f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a315560e07f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d25560fc7fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eed81905560056000527fbfd358e93f18da3ed276c3afdbdba00b8f0b6008a03476a6a86bd6320ee6938b556200097260016001600160e01b0362000c9c16565b7fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f5560036000819052602081815260008051602062002aa383398151915254620009e69291620009d791606491620006db91906023906200173362000b9e821b17901c565b6001600160e01b0362000cc516565b600360005260086020527f625b35f5e76f098dd7c3a05b10e2e5e78a4a01228d60c3b143426cdf36d264555562000a2760046001600160e01b0362000c9c16565b600460005260086020527f9321edea6e3be4df59a344b401fab4f888b556fda1f954244cff9204bad624b85562000a6860056001600160e01b0362000c9c16565b600560005260086020527f91238f30f286c9a1c6e901c4eda3b214c381c846e3dbe48df95c21488e8e1fdb555062000d77945050505050565b3b151590565b6001600160a01b03811662000b1d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f696e76616c696420616464726573730000000000000000000000000000000000604482015290519081900360640190fd5b50565b60008282018381101562000b9557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b60008262000baf5750600062000b98565b8282028284828162000bbd57fe5b041462000b95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018062002a626021913960400191505060405180910390fd5b600080821162000c8757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848162000c9357fe5b04949350505050565b60ff811660009081526009602052604081205462000b989083906001600160e01b0362000cc516565b60ff8216600090815260066020908152604080832054600383529083205462000b9592620006db91908690620017ff62000cff821b17901c565b60008282111562000d7157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b611c3b8062000d876000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638d3ce69d1161010f578063b2cec8ea116100a2578063cbecb28811610071578063cbecb2881461050a578063f049f33414610512578063f2fde38b14610532578063fc0c546a14610558576101e5565b8063b2cec8ea146104a2578063b99ef521146104c2578063bac883ef146104e2578063bd4b2be914610502576101e5565b8063983c44d6116100de578063983c44d6146103b75780639972444f146103bf578063a3df582a146103df578063a4c0ed36146103e7576101e5565b80638d3ce69d146103635780638d3df3461461036b5780638da5cb5b1461038b5780638f32d59b146103af576101e5565b8063392e53cd11610187578063622c5e4511610156578063622c5e451461032b578063715018a6146103335780637af7c0401461033b5780638129fc1c1461035b576101e5565b8063392e53cd146102b757806359791d6d146102bf5780635f26622f146102df578063604f21771461030b576101e5565b80630f10e06f116101c35780630f10e06f146102695780632755731e14610289578063375a4cab14610291578063381a4113146102af576101e5565b8063014a969a146101ea578063047fc9aa1461021e57806304a3922014610238575b600080fd5b61020a6004803603602081101561020057600080fd5b503560ff16610560565b604080519115158252519081900360200190f35b610226610575565b60408051918252519081900360200190f35b6102676004803603604081101561024e57600080fd5b50803560ff1690602001356001600160a01b0316610584565b005b6102266004803603602081101561027f57600080fd5b503560ff166106d0565b6102266106e2565b6102996106e8565b6040805160ff9092168252519081900360200190f35b61020a6106ed565b61020a6106f6565b610226600480360360208110156102d557600080fd5b503560ff16610704565b610267600480360360408110156102f557600080fd5b506001600160a01b038135169060200135610716565b6102266004803603602081101561032157600080fd5b503560ff16610fc4565b610299610fd6565b610267610fdb565b61020a6004803603602081101561035157600080fd5b503560ff16611073565b610267611088565b6102996111de565b6102266004803603602081101561038157600080fd5b503560ff166111e3565b6103936111f5565b604080516001600160a01b039092168252519081900360200190f35b61020a611204565b610299611215565b610393600480360360208110156103d557600080fd5b503560ff1661121a565b610226611235565b61020a600480360360608110156103fd57600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561042d57600080fd5b82018360208201111561043f57600080fd5b8035906020019184600183028401116401000000008311171561046157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061123b945050505050565b610226600480360360208110156104b857600080fd5b503560ff16611274565b610226600480360360208110156104d857600080fd5b503560ff16611286565b610267600480360360208110156104f857600080fd5b503560ff16611298565b610299611652565b610299611657565b6102266004803603602081101561052857600080fd5b503560ff1661165c565b6102676004803603602081101561054857600080fd5b50356001600160a01b031661166e565b6103936116d3565b600b6020526000908152604090205460ff1681565b6a070fe2cd68c25ff4f0000081565b60ff821660011480610599575060ff82166005145b6105d7576040805162461bcd60e51b815260206004820152600a6024820152691ddc9bdb99c81c1bdbdb60b21b604482015290519081900360640190fd5b60ff82166000908152600260205260409020546001600160a01b03163314610637576040805162461bcd60e51b815260206004820152600e60248201526d1b9bdd08185d5d1a1bdc9a5e995960921b604482015290519081900360640190fd5b610640816116e2565b60ff82166000818152600260209081526040918290205482516001600160a01b0391821681529085169181019190915281517f09a67390cbf7986a6bb0fcb44307b4844ba258bca3f38599d2b344824df4ba1d929181900390910190a260ff91909116600090815260026020526040902080546001600160a01b0319166001600160a01b03909216919091179055565b60056020526000908152604090205481565b600d5481565b600581565b600e5460ff1681565b600e54610100900460ff1681565b60086020526000908152604090205481565b61071e611204565b61076f576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600e5460ff16156107c7576040805162461bcd60e51b815260206004820152601760248201527f616c7265616479207072652d696e697469616c697a6564000000000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b038481169190911791829055604080516370a0823160e01b81523060048201529051600093909216916370a0823191602480820192602092909190829003018186803b15801561082b57600080fd5b505afa15801561083f573d6000803e3d6000fd5b505050506040513d602081101561085557600080fd5b505190506a070fe2cd68c25ff4f0000081146108b1576040805162461bcd60e51b815260206004820152601660248201527577726f6e6720636f6e74726163742062616c616e636560501b604482015290519081900360640190fd5b6108b961172f565b600d55600e805460ff191660011790556003600090815260026020527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c3546040805163189acdbd60e31b81526001600160a01b0387811660048301529151919092169263c4d66de8926024808201939182900301818387803b15801561093e57600080fd5b505af1158015610952573d6000803e3d6000fd5b50506004600081815260026020527fee60d0579bcffd98e668647d59fec1ff86a7fb340ce572e844f234ae73a6918f546040805163189acdbd60e31b81526001600160a01b038a811695820195909552905193909116945063c4d66de893506024808201939182900301818387803b1580156109cd57600080fd5b505af11580156109e1573d6000803e3d6000fd5b5050600360008181526020919091527fcbc4e5fb02c3d1de23a9f1e014b4d2ee5aeaea9505df5e855c9210bf472495af54909250610a3a9150606490610a2e90601963ffffffff61173316565b9063ffffffff61179516565b600154600260009081527f679795a0195a1b76cdebb7c51d74e058aee92919b8c3389af86ef24535e8a28c54600360209081527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d546040805163238a3fe160e01b81526001600160a01b039485166004820152602481019290925251959650919093169363238a3fe19360448084019491938390030190829087803b158015610ae257600080fd5b505af1158015610af6573d6000803e3d6000fd5b505050506040513d6020811015610b0c57600080fd5b505060015460036000908152600260209081527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c3546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018790529051919094169363a9059cbb9360448083019493928390030190829087803b158015610b9157600080fd5b505af1158015610ba5573d6000803e3d6000fd5b505050506040513d6020811015610bbb57600080fd5b50506006600090815260036020527fc69056f16cbaa3c616b828e333ab7d3a32310765507f8f58359e99ebb7a885f354610bfb908563ffffffff6117ff16565b60015460066000908152600260209081527f59dd4b18488d12f51eda69757a0ed42a2010c14b564330cc74a06895e60c077b546040805163238a3fe160e01b81526001600160a01b03928316600482015260248101879052905195965093169363238a3fe193604480820194918390030190829087803b158015610c7e57600080fd5b505af1158015610c92573d6000803e3d6000fd5b505050506040513d6020811015610ca857600080fd5b50508315610d35576001546040805163238a3fe160e01b81526000600482018190526024820188905291516001600160a01b039093169263238a3fe192604480840193602093929083900390910190829087803b158015610d0857600080fd5b505af1158015610d1c573d6000803e3d6000fd5b505050506040513d6020811015610d3257600080fd5b50505b60026000527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d5460046020527f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a754610d929163ffffffff6117ff16565b60046020527f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a75560036000527f2e174c10e159ea99b867ce3205125c24a42d128804e4070ed6fcc8cc98166aa054610df0908363ffffffff6117ff16565b7f2e174c10e159ea99b867ce3205125c24a42d128804e4070ed6fcc8cc98166aa05560066000527fc69056f16cbaa3c616b828e333ab7d3a32310765507f8f58359e99ebb7a885f35460046020527fc59312466997bb42aaaf719ece141047820e6b34531e1670dc1852a453648f0f54610e6f9163ffffffff6117ff16565b6006600052600460209081527fc59312466997bb42aaaf719ece141047820e6b34531e1670dc1852a453648f0f91909155604080516001600160a01b0388168152339281019290925280517f20e0b9d27e138a83ff1b3f687932144f5e913aa93855ac36c2611ec1dfae704e9281900390910190a160026000819052600360209081527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d546040805191825233928201929092528151600080516020611b49833981519152929181900390910190a2604080518381523360208201528151600392600080516020611b49833981519152928290030190a2604080518281523360208201528151600692600080516020611b49833981519152928290030190a28315610fbd57604080518581523360208201528151600092600080516020611b49833981519152928290030190a25b5050505050565b60036020526000908152604090205481565b600481565b610fe3611204565b611034576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152600f60248201526e1b9bdd081a5b5c1b195b595b9d1959608a1b604482015290519081900360640190fd5b600a6020526000908152604090205460ff1681565b600e5460ff166110d5576040805162461bcd60e51b81526020600482015260136024820152721b9bdd081c1c994b5a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b600e54610100900460ff1615611128576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b6276a700611146600d5461113a61172f565b9063ffffffff6117ff16565b101561118f57611154611204565b61118f5760405162461bcd60e51b8152600401808060200182810382526027815260200180611b226027913960400191505060405180910390fd5b61119761172f565b600c55600e805461ff0019166101001790556040805133815290517f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e69181900360200190a1565b600381565b60066020526000908152604090205481565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b600181565b6002602052600090815260409020546001600160a01b031681565b600c5481565b600060405162461bcd60e51b815260040180806020018281038252602e815260200180611bb0602e913960400191505060405180910390fd5b60096020526000908152604090205481565b60046020526000908152604090205481565b600e54610100900460ff166112e6576040805162461bcd60e51b815260206004820152600f60248201526e1b9bdd081a5b9a5d1a585b1a5e9959608a1b604482015290519081900360640190fd5b60ff8116600090815260056020526040902054600c54829161130e919063ffffffff61185c16565b61131661172f565b10158015611336575060ff8082166000908152600b602052604090205416155b6113715760405162461bcd60e51b8152600401808060200182810382526029815260200180611bde6029913960400191505060405180910390fd5b60ff821660031480611386575060ff82166004145b80611394575060ff82166001145b806113a2575060ff82166005145b6113e0576040805162461bcd60e51b815260206004820152600a6024820152691ddc9bdb99c81c1bdbdb60b21b604482015290519081900360640190fd5b60ff8083166000908152600a6020526040812054909116611426575060ff8216600090815260096020908152604080832054600a909252909120805460ff191660011790555b6000611431846118b6565b60ff85166000908152600860205260409020549091506114689061145b908363ffffffff61173316565b839063ffffffff61185c16565b9150600082116114bf576040805162461bcd60e51b815260206004820152601960248201527f6e6f20696e7374616c6c6d656e747320617661696c61626c6500000000000000604482015290519081900360640190fd5b60006114cc8584846119a0565b90506114de838263ffffffff61185c16565b925060ff8516600314806114f5575060ff85166004145b156115905760015460ff8616600090815260026020908152604080832054815163a9059cbb60e01b81526001600160a01b03918216600482015260248101899052915194169363a9059cbb93604480840194938390030190829087803b15801561155e57600080fd5b505af1158015611572573d6000803e3d6000fd5b505050506040513d602081101561158857600080fd5b506116219050565b60015460ff8616600090815260026020908152604080832054815163238a3fe160e01b81526001600160a01b03918216600482015260248101899052915194169363238a3fe193604480840194938390030190829087803b1580156115f457600080fd5b505af1158015611608573d6000803e3d6000fd5b505050506040513d602081101561161e57600080fd5b50505b60408051848152336020820152815160ff881692600080516020611b49833981519152928290030190a25050505050565b600681565b600281565b60076020526000908152604090205481565b611676611204565b6116c7576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6116d081611a5d565b50565b6001546001600160a01b031681565b6001600160a01b0381166116d0576040805162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b604482015290519081900360640190fd5b4290565b6000826117425750600061178f565b8282028284828161174f57fe5b041461178c5760405162461bcd60e51b8152600401808060200182810382526021815260200180611b8f6021913960400191505060405180910390fd5b90505b92915050565b60008082116117eb576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816117f657fe5b04949350505050565b600082821115611856576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008282018381101561178c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60ff811660009081526007602052604081205481906118de906201518063ffffffff61173316565b60ff8416600090815260056020526040812054600c54929350909161191a91849161190e9163ffffffff61185c16565b9063ffffffff61185c16565b905061192f62015180610a2e8361113a61172f565b60ff851660009081526006602090815260408083205460079092529091205491945090611962908563ffffffff61185c16565b11156119995760ff84166000908152600760209081526040808320546006909252909120546119969163ffffffff6117ff16565b92505b5050919050565b60ff831660009081526004602052604081205481906119c5908563ffffffff6117ff16565b60ff86166000908152600460209081526040808320939093556007905220546119f4908463ffffffff61185c16565b60ff861660009081526007602081815260408084208590556006825290922054915211611a555760ff851660009081526004602052604090205415611a4c575060ff8416600090815260046020526040812080549190555b611a5585611afd565b949350505050565b6001600160a01b038116611aa25760405162461bcd60e51b8152600401808060200182810382526026815260200180611b696026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60ff166000908152600b60205260409020805460ff19166001179055565b3b15159056fe666f72206e6f77206f6e6c79206f776e65722063616e2063616c6c2074686973206d6574686f64a8b65b82b2ff2a955e75c1bfa6a0e92aafb764156295da77a0a4c714f3895c724f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7773656e64696e6720746f6b656e7320746f207468697320636f6e7472616374206973206e6f7420616c6c6f776564696e7374616c6c6d656e747320617265206e6f742061637469766520666f72207468697320706f6f6ca265627a7a723058208fc7fe0d6f40178495c4e655627ac8a6bc837eb89686042a07161f078a2ea04464736f6c634300050a0032c3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4da15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054cc69056f16cbaa3c616b828e333ab7d3a32310765507f8f58359e99ebb7a885f383ec6a1f0257b830b5e016457c9cf1435391bf56cc98f369a58a54fe93772465ee60d0579bcffd98e668647d59fec1ff86a7fb340ce572e844f234ae73a6918f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77405aad32e1adbac89bb7f176e338b8fc6e994ca210c9bb7bdca249b465942250cbc4e5fb02c3d1de23a9f1e014b4d2ee5aeaea9505df5e855c9210bf472495af00000000000000000000000086edd0c110d1fc7f8a5e1108623b3b1b4e3740f90000000000000000000000000df05adac0159e215111696339ad4998e5871b3d0000000000000000000000003cfe51b61e25750ab1426b0072e5d0cc5c30aafa0000000000000000000000000218b706898d234b85d2494df21eb0677eaea91800000000000000000000000086edd0c110d1fc7f8a5e1108623b3b1b4e3740f90000000000000000000000000df05adac0159e215111696339ad4998e5871b3d"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.5.10+commit.5a6ea5b1",
          "evm_version" => "default",
          "name" => "Distribution",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "00000000000000000000000086edd0c110d1fc7f8a5e1108623b3b1b4e3740f90000000000000000000000000df05adac0159e215111696339ad4998e5871b3d0000000000000000000000003cfe51b61e25750ab1426b0072e5d0cc5c30aafa0000000000000000000000000218b706898d234b85d2494df21eb0677eaea91800000000000000000000000086edd0c110d1fc7f8a5e1108623b3b1b4e3740f90000000000000000000000000df05adac0159e215111696339ad4998e5871b3d"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end

      test "another failed constructor args verification" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_with_constructor_args.sol"
          |> File.read!()

        bytecode =
          "0x60806040523661001357610011610017565b005b6100115b61002761002261005e565b610096565b565b606061004e838360405180606001604052806027815260200161024c602791396100ba565b9392505050565b3b151590565b90565b60006100917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e8080156100b5573d6000f35b3d6000fd5b6060833b61011e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084015b60405180910390fd5b600080856001600160a01b03168560405161013991906101cc565b600060405180830381855af49150503d8060008114610174576040519150601f19603f3d011682016040523d82523d6000602084013e610179565b606091505b5091509150610189828286610193565b9695505050505050565b606083156101a257508161004e565b8251156101b25782518084602001fd5b8160405162461bcd60e51b815260040161011591906101e8565b600082516101de81846020870161021b565b9190910192915050565b600060208252825180602084015261020781604085016020870161021b565b601f01601f19169190910160400192915050565b60005b8381101561023657818101518382015260200161021e565b83811115610245576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209b8470f06e8a3960c912103fc2be177edaad69584ee3c7d2809ee737e79408e764736f6c63430008020033"

        contract_creation_code =
          "0x6080604052604051610772380380610772833981016040819052610022916102f7565b61004d60017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd61040f565b60008051602061072b8339815191521461007757634e487b7160e01b600052600160045260246000fd5b6100838282600061008a565b5050610474565b610093836100f4565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806100d45750805b156100ef576100ed83836101b460201b6100291760201c565b505b505050565b610107816101e060201b6100551760201c565b61016e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b8061019360008051602061072b83398151915260001b6101e660201b61005b1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606101d9838360405180606001604052806027815260200161074b602791396101e9565b9392505050565b3b151590565b90565b6060833b6102485760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610165565b600080856001600160a01b03168560405161026391906103c0565b600060405180830381855af49150503d806000811461029e576040519150601f19603f3d011682016040523d82523d6000602084013e6102a3565b606091505b5090925090506102b48282866102be565b9695505050505050565b606083156102cd5750816101d9565b8251156102dd5782518084602001fd5b8160405162461bcd60e51b815260040161016591906103dc565b60008060408385031215610309578182fd5b82516001600160a01b038116811461031f578283fd5b60208401519092506001600160401b038082111561033b578283fd5b818501915085601f83011261034e578283fd5b8151818111156103605761036061045e565b604051601f8201601f19908116603f011681019083821181831017156103885761038861045e565b816040528281528860208487010111156103a0578586fd5b6103b1836020830160208801610432565b80955050505050509250929050565b600082516103d2818460208701610432565b9190910192915050565b60006020825282518060208401526103fb816040850160208701610432565b601f01601f19169190910160400192915050565b60008282101561042d57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561044d578181015183820152602001610435565b838111156100ed5750506000910152565b634e487b7160e01b600052604160045260246000fd5b6102a8806104836000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261005e565b610096565b565b606061004e838360405180606001604052806027815260200161024c602791396100ba565b9392505050565b3b151590565b90565b60006100917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b3660008037600080366000845af43d6000803e8080156100b5573d6000f35b3d6000fd5b6060833b61011e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084015b60405180910390fd5b600080856001600160a01b03168560405161013991906101cc565b600060405180830381855af49150503d8060008114610174576040519150601f19603f3d011682016040523d82523d6000602084013e610179565b606091505b5091509150610189828286610193565b9695505050505050565b606083156101a257508161004e565b8251156101b25782518084602001fd5b8160405162461bcd60e51b815260040161011591906101e8565b600082516101de81846020870161021b565b9190910192915050565b600060208252825180602084015261020781604085016020870161021b565b601f01601f19169190910160400192915050565b60005b8381101561023657818101518382015260200161021e565b83811115610245576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209b8470f06e8a3960c912103fc2be177edaad69584ee3c7d2809ee737e79408e764736f6c63430008020033360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564000000000000000000000000569e7b559a3af9b2350b8db2afd8977b8bd0517200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000024c4d66de8000000000000000000000000217373ab5e0082b2ce622169672eca6f4462319c00000000000000000000000000000000000000000000000000000000"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.2+commit.661d1103",
          "evm_version" => "default",
          "name" => "ERC1967Proxy",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "000000000000000000000000569e7b559a3af9b2350b8db2afd8977b8bd0517200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000024c4d66de8000000000000000000000000217373ab5e0082b2ce622169672eca6f4462319c00000000000000000000000000000000000000000000000000000000"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end
    end

    describe "another regression tests" do
      test "accepting correct constructor args" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_5114.sol"
          |> File.read!()

        bytecode =
          "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ed565b610118565b61005b610093366004610707565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ed565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b03161415610159576101548161040b565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b606061029183836040518060600160405280602781526020016108016027913961045f565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b600061035061053a565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b583610562565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103f65750805b156101d557610405838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610434610379565b604080516001600160a01b03928316815291841660208301520160405180910390a161016181610611565b606061046a84610298565b6104c55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104e09190610785565b600060405180830381855af49150503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b509150915061053082828661069d565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61056b81610298565b6105cd5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381166106765760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105f0565b606083156106ac575081610291565b8251156106bc5782518084602001fd5b8160405162461bcd60e51b815260040161033891906107a1565b80356001600160a01b038116811461029d57600080fd5b6000602082840312156106fe578081fd5b610291826106d6565b60008060006040848603121561071b578182fd5b610724846106d6565b9250602084013567ffffffffffffffff80821115610740578384fd5b818601915086601f830112610753578384fd5b813581811115610761578485fd5b876020828501011115610772578485fd5b6020830194508093505050509250925092565b600082516107978184602087016107d4565b9190910192915050565b60006020825282518060208401526107c08160408501602087016107d4565b601f01601f19169190910160400192915050565b60005b838110156107ef5781810151838201526020016107d7565b83811115610405575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122016ea36e15be10f9560025e0ec9401e2e9110cb5ec41d110b4a0e391838c1f19b64736f6c63430008020033"

        contract_creation_code =
          "0x608060405260405162000f4038038062000f408339810160408190526200002691620004d4565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd62000603565b60008051602062000ef9833981519152146200008157634e487b7160e01b600052600160045260246000fd5b6200008f82826000620000ff565b50620000bf905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610462000603565b60008051602062000ed983398151915214620000eb57634e487b7160e01b600052600160045260246000fd5b620000f68262000170565b5050506200066c565b6200010a83620001cb565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806200014c5750805b156200016b576200016983836200029360201b6200026c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200019b620002c2565b604080516001600160a01b03928316815291841660208301520160405180910390a1620001c881620002fb565b50565b620001e1816200038b60201b620002981760201c565b620002495760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b806200027260008051602062000ef983398151915260001b6200039560201b620002141760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060620002bb838360405180606001604052806027815260200162000f196027913962000398565b9392505050565b6000620002ec60008051602062000ed983398151915260001b6200039560201b620002141760201c565b546001600160a01b0316905090565b6001600160a01b038116620003625760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840162000240565b806200027260008051602062000ed983398151915260001b6200039560201b620002141760201c565b803b15155b919050565b90565b6060620003a5846200038b565b620004025760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b0316856040516200041f9190620005b0565b600060405180830381855af49150503d80600081146200045c576040519150601f19603f3d011682016040523d82523d6000602084013e62000461565b606091505b509092509050620004748282866200047e565b9695505050505050565b606083156200048f575081620002bb565b825115620004a05782518084602001fd5b8160405162461bcd60e51b8152600401620002409190620005ce565b80516001600160a01b03811681146200039057600080fd5b600080600060608486031215620004e9578283fd5b620004f484620004bc565b92506200050460208501620004bc565b60408501519092506001600160401b038082111562000521578283fd5b818601915086601f83011262000535578283fd5b8151818111156200054a576200054a62000656565b604051601f8201601f19908116603f0116810190838211818310171562000575576200057562000656565b816040528281528960208487010111156200058e578586fd5b620005a183602083016020880162000627565b80955050505050509250925092565b60008251620005c481846020870162000627565b9190910192915050565b6000602082528251806020840152620005ef81604085016020870162000627565b601f01601f19169190910160400192915050565b6000828210156200062257634e487b7160e01b81526011600452602481fd5b500390565b60005b83811015620006445781810151838201526020016200062a565b83811115620001695750506000910152565b634e487b7160e01b600052604160045260246000fd5b61085d806200067c6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ed565b610118565b61005b610093366004610707565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ed565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b03161415610159576101548161040b565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b606061029183836040518060600160405280602781526020016108016027913961045f565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b600061035061053a565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b583610562565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103f65750805b156101d557610405838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610434610379565b604080516001600160a01b03928316815291841660208301520160405180910390a161016181610611565b606061046a84610298565b6104c55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104e09190610785565b600060405180830381855af49150503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b509150915061053082828661069d565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61056b81610298565b6105cd5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381166106765760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105f0565b606083156106ac575081610291565b8251156106bc5782518084602001fd5b8160405162461bcd60e51b815260040161033891906107a1565b80356001600160a01b038116811461029d57600080fd5b6000602082840312156106fe578081fd5b610291826106d6565b60008060006040848603121561071b578182fd5b610724846106d6565b9250602084013567ffffffffffffffff80821115610740578384fd5b818601915086601f830112610753578384fd5b813581811115610761578485fd5b876020828501011115610772578485fd5b6020830194508093505050509250925092565b600082516107978184602087016107d4565b9190910192915050565b60006020825282518060208401526107c08160408501602087016107d4565b601f01601f19169190910160400192915050565b60005b838110156107ef5781810151838201526020016107d7565b83811115610405575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122016ea36e15be10f9560025e0ec9401e2e9110cb5ec41d110b4a0e391838c1f19b64736f6c63430008020033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c65640000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.2+commit.661d1103",
          "evm_version" => "default",
          "name" => "TransparentUpgradeableProxy",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => false,
          "constructor_arguments" =>
            "0000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"
        }

        assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
        assert abi != nil
      end

      test "issue 4758" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_4758.sol"
          |> File.read!()

        bytecode =
          "0x6080604052600436106101135760003560e01c8063759bd1fe116100a0578063a97eaba711610064578063a97eaba7146102db578063b7ec2086146102f1578063c7802ba214610306578063dd48f77414610326578063e2fa9ee01461034657600080fd5b8063759bd1fe146102535780638e8fa11f1461026657806390ffb8641461028657806391b7f5ed146102a65780639b6dbc8a146102c657600080fd5b80634707d000116100e75780634707d000146101c357806347535d7b146101e55780634a1bb6b41461020a57806353cdef02146102205780636aa7c1ab1461024057600080fd5b8062c0f916146101185780632481bb5c146101555780632ae3dc741461017557806339c4576214610195575b600080fd5b34801561012457600080fd5b50610138610133366004611be4565b610366565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561016157600080fd5b50600054610138906001600160a01b031681565b34801561018157600080fd5b50610138610190366004611a62565b610386565b3480156101a157600080fd5b506101b56101b0366004611a62565b6103f6565b60405190815260200161014c565b3480156101cf57600080fd5b506101e36101de366004611aca565b610492565b005b3480156101f157600080fd5b506101fa61064d565b604051901515815260200161014c565b34801561021657600080fd5b506101b560045481565b34801561022c57600080fd5b506101e361023b366004611aae565b610667565b6101e361024e36600461197b565b6107e2565b6101e3610261366004611b02565b610ad5565b34801561027257600080fd5b506101e36102813660046119f3565b610b11565b34801561029257600080fd5b506101fa6102a1366004611a62565b610c95565b3480156102b257600080fd5b506101e36102c1366004611be4565b610ca9565b3480156102d257600080fd5b506101e3610df6565b3480156102e757600080fd5b506101b560055481565b3480156102fd57600080fd5b506101b5610ed4565b34801561031257600080fd5b506101e3610321366004611b63565b610ff8565b34801561033257600080fd5b506101e3610341366004611aca565b6113d1565b34801561035257600080fd5b506101e3610361366004611be4565b6114e5565b6006816004811061037657600080fd5b01546001600160a01b0316905081565b600060068260018111156103aa57634e487b7160e01b600052602160045260246000fd5b846103b65760006103b9565b60025b60ff166103c69190611e6e565b600481106103e457634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03169392505050565b6001546000906001600160a01b03166370a082316104148585610386565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561045357600080fd5b505afa158015610467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048b9190611a96565b9392505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906104c090600401611ce8565b60206040518083038186803b1580156104d857600080fd5b505afa1580156104ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610510919061195f565b6001600160a01b0316336001600160a01b0316146105495760405162461bcd60e51b815260040161054090611da8565b60405180910390fd5b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a082319060240160206040518083038186803b15801561059257600080fd5b505afa1580156105a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca9190611a96565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561061057600080fd5b505af1158015610624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106489190611a46565b505050565b60008060055411801561066257506005544210155b905090565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061069590600401611dfe565b60206040518083038186803b1580156106ad57600080fd5b505afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e5919061195f565b6001600160a01b0316336001600160a01b0316146107155760405162461bcd60e51b815260040161054090611e23565b6001600160a01b0381166107875760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527234b233b2903230ba309031b7b73a3930b1ba1760691b6064820152608401610540565b600080546040516001600160a01b03808516939216917f6a6e057f21cc834cf349d8150e92867f52cb34d54375f174c09c431538c3dfb991a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6107ea61064d565b151560011461080b5760405162461bcd60e51b815260040161054090611d5d565b826108585760405162461bcd60e51b815260206004820152601d60248201527f596f75206e65656420746f2061636365707420746865207465726d732e0000006044820152606401610540565b806108755760405162461bcd60e51b815260040161054090611d18565b6000806108828287610386565b6001546040516370a0823160e01b81526001600160a01b038084166004830152929350600092909116906370a082319060240160206040518083038186803b1580156108cd57600080fd5b505afa1580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190611a96565b9050600081116109575760405162461bcd60e51b815260206004820181905260248201527f5468652072657175657374656420617373657420697320736f6c64206f75742e6044820152606401610540565b6000610961610ed4565b9050803410156109ca5760405162461bcd60e51b815260206004820152602e60248201527f53656e6420656e6f7567682063757272656e637920746f20706179206174206c60448201526d32b0b9ba1037b7329034ba32b69760911b6064820152608401610540565b60006109d68234611e86565b9050828111156109e35750815b60006109ef8383611ea6565b9050610a008b8b84898989896115ce565b60005460405163bf40fac160e01b815260206004820152600b60248201526a62656e656669636961727960a81b6044820152610aac9183916001600160a01b039091169063bf40fac19060640160206040518083038186803b158015610a6557600080fd5b505afa158015610a79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9d919061195f565b6001600160a01b0316906117eb565b80341115610ac857610ac8610ac18234611ec5565b33906117eb565b5050505050505050505050565b610add61064d565b1515600114610afe5760405162461bcd60e51b815260040161054090611d5d565b610b0b33858585856107e2565b50505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610b3f90600401611ce8565b60206040518083038186803b158015610b5757600080fd5b505afa158015610b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8f919061195f565b6001600160a01b0316336001600160a01b031614610bbf5760405162461bcd60e51b815260040161054090611da8565b6001600160a01b038316610c155760405162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c696420726576657273652072656769737472617200006044820152606401610540565b60405163c47f002760e01b81526001600160a01b0384169063c47f002790610c439085908590600401611cb9565b602060405180830381600087803b158015610c5d57600080fd5b505af1158015610c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0b9190611a96565b6000610ca183836103f6565b159392505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610cd790600401611dfe565b60206040518083038186803b158015610cef57600080fd5b505afa158015610d03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d27919061195f565b6001600160a01b0316336001600160a01b031614610d575760405162461bcd60e51b815260040161054090611e23565b60008111610db55760405162461bcd60e51b815260206004820152602560248201527f596f75206e65656420746f2070726f766964652061206e6f6e2d7a65726f20706044820152643934b1b29760d91b6064820152608401610540565b60045460408051918252602082018390527f8aa4fa52648a6d15edce8a179c792c86f3719d0cc3c572cf90f91948f0f2cb68910160405180910390a1600455565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610e2490600401611dfe565b60206040518083038186803b158015610e3c57600080fd5b505afa158015610e50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e74919061195f565b6001600160a01b0316336001600160a01b031614610ea45760405162461bcd60e51b815260040161054090611e23565b600060058190556040517f589bfff7e7b59e33b97fa923dbc99256a6d2fdf9a631b431fa2dc06f4eea0ded9190a1565b6000805460405163bf40fac160e01b81526020600482015260066024820152654f7261636c6560d01b60448201526064916001600160a01b03169063bf40fac190830160206040518083038186803b158015610f2f57600080fd5b505afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f67919061195f565b60405163048cc1a760e51b8152600060048201526001600160a01b03919091169063919834e09060240160206040518083038186803b158015610fa957600080fd5b505afa158015610fbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe19190611a96565b600454610fee9190611ea6565b6106629190611e86565b61100061064d565b15156001146110215760405162461bcd60e51b815260040161054090611d5d565b8261106e5760405162461bcd60e51b815260206004820152601d60248201527f596f75206e65656420746f2061636365707420746865207465726d732e0000006044820152606401610540565b8061108b5760405162461bcd60e51b815260040161054090611d18565b6001600087828111156110ae57634e487b7160e01b600052602160045260246000fd5b905060006110bc838a610386565b6001546040516370a0823160e01b81526001600160a01b038084166004830152929350600092909116906370a082319060240160206040518083038186803b15801561110757600080fd5b505afa15801561111b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113f9190611a96565b9050808911156111a95760405162461bcd60e51b815260206004820152602f60248201527f4e6f7420656e6f7567682061737365747320617661696c61626c6520746f206260448201526e3abc903a3430ba1030b6b7bab73a1760891b6064820152608401610540565b600254604051627eeac760e11b8152336004820152602481018590528a916001600160a01b03169062fdd58e9060440160206040518083038186803b1580156111f157600080fd5b505afa158015611205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112299190611a96565b10156112ad5760405162461bcd60e51b815260206004820152604760248201527f596f75206e65656420746f206f776e20656e6f7567682070726573616c65207660448201527f6f75636865727320746f2072656465656d20746865207370656369666965642060648201526630b6b7bab73a1760c91b608482015260a401610540565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337019050509050848260008151811061131457634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508a8160008151811061134257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600254604051637507c42960e11b81526001600160a01b039091169063ea0f88529061138190339086908690600401611c36565b600060405180830381600087803b15801561139b57600080fd5b505af11580156113af573d6000803e3d6000fd5b505050506113c38a8d8d89888860006115ce565b505050505050505050505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906113ff90600401611ce8565b60206040518083038186803b15801561141757600080fd5b505afa15801561142b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144f919061195f565b6001600160a01b0316336001600160a01b03161461147f5760405162461bcd60e51b815260040161054090611da8565b60405163a22cb46560e01b81526001600160a01b0382811660048301526001602483015283169063a22cb46590604401600060405180830381600087803b1580156114c957600080fd5b505af11580156114dd573d6000803e3d6000fd5b505050505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061151390600401611dfe565b60206040518083038186803b15801561152b57600080fd5b505afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611563919061195f565b6001600160a01b0316336001600160a01b0316146115935760405162461bcd60e51b815260040161054090611e23565b60058190556040518181527f397a093f9e29b7327f453f9672278c54e4daed6b689ee9bb458ae76800452ad59060200160405180910390a150565b60005b858110156117e157600180546000916001600160a01b0390911690632f745c599087906115fe8689611ec5565b6116089190611ec5565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561164c57600080fd5b505afa158015611660573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116849190611a96565b600154604051632142170760e11b81526001600160a01b0388811660048301528c81166024830152604482018490529293509116906342842e0e90606401600060405180830381600087803b1580156116dc57600080fd5b505af11580156116f0573d6000803e3d6000fd5b505050508088600181111561171557634e487b7160e01b600052602160045260246000fd5b604080516001600160a01b038d168152891515602082015290810186905233907f1682a2a055cfda159fc278195b31d5f7ab61f5128c423fa0ea2bf511565a9b6d9060600160405180910390a46003546001805460405163ebaf492d60e01b81526001600160a01b039384169363ebaf492d9361179b9390911691869190600401611c76565b600060405180830381600087803b1580156117b557600080fd5b505af11580156117c9573d6000803e3d6000fd5b505050505080806117d990611edc565b9150506115d1565b5050505050505050565b8047101561183b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610540565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611888576040519150601f19603f3d011682016040523d82523d6000602084013e61188d565b606091505b50509050806106485760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610540565b80356002811061191357600080fd5b919050565b60008083601f840112611929578182fd5b50813567ffffffffffffffff811115611940578182fd5b60208301915083602082850101111561195857600080fd5b9250929050565b600060208284031215611970578081fd5b815161048b81611f0d565b600080600080600060808688031215611992578081fd5b853561199d81611f0d565b94506119ab60208701611904565b935060408601356119bb81611f25565b9250606086013567ffffffffffffffff8111156119d6578182fd5b6119e288828901611918565b969995985093965092949392505050565b600080600060408486031215611a07578283fd5b8335611a1281611f0d565b9250602084013567ffffffffffffffff811115611a2d578283fd5b611a3986828701611918565b9497909650939450505050565b600060208284031215611a57578081fd5b815161048b81611f25565b60008060408385031215611a74578182fd5b8235611a7f81611f25565b9150611a8d60208401611904565b90509250929050565b600060208284031215611aa7578081fd5b5051919050565b600060208284031215611abf578081fd5b813561048b81611f0d565b60008060408385031215611adc578182fd5b8235611ae781611f0d565b91506020830135611af781611f0d565b809150509250929050565b60008060008060608587031215611b17578384fd5b611b2085611904565b93506020850135611b3081611f25565b9250604085013567ffffffffffffffff811115611b4b578283fd5b611b5787828801611918565b95989497509550505050565b60008060008060008060a08789031215611b7b578081fd5b611b8487611904565b9550602087013594506040870135611b9b81611f0d565b93506060870135611bab81611f25565b9250608087013567ffffffffffffffff811115611bc6578182fd5b611bd289828a01611918565b979a9699509497509295939492505050565b600060208284031215611bf5578081fd5b5035919050565b6000815180845260208085019450808401835b83811015611c2b57815187529582019590820190600101611c0f565b509495945050505050565b6001600160a01b0384168152606060208201819052600090611c5a90830185611bfc565b8281036040840152611c6c8185611bfc565b9695505050505050565b6001600160a01b0384168152602081018390526060810160048310611cab57634e487b7160e01b600052602160045260246000fd5b826040830152949350505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6020808252601690820152751d1bdad95b905cdcda59db9b595b9d10dbdb9d1c9bdb60521b604082015260600190565b60208082526025908201527f596f75206e65656420746f2073656e642074686520616363657074616e6365206040820152643a32bc3a1760d91b606082015260800190565b6020808252602b908201527f546869732063616c6c206f6e6c7920776f726b73207768656e2074686520736860408201526a37b81034b99037b832b71760a91b606082015260800190565b60208082526036908201527f746f6b656e41737369676e6d656e74436f6e74726f6c206b65792072657175696040820152753932b2103337b9103a3434b990333ab731ba34b7b71760511b606082015260800190565b6020808252600b908201526a1cda1bdc10dbdb9d1c9bdb60aa1b604082015260600190565b6020808252602b908201527f73686f70436f6e74726f6c206b657920726571756972656420666f722074686960408201526a3990333ab731ba34b7b71760a91b606082015260800190565b60008219821115611e8157611e81611ef7565b500190565b600082611ea157634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611ec057611ec0611ef7565b500290565b600082821015611ed757611ed7611ef7565b500390565b6000600019821415611ef057611ef0611ef7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114611f2257600080fd5b50565b8015158114611f2257600080fdfea2646970667358221220f2e9ba9e74b25591261868f1d84c2beef56c6930ea91cecb35779eaf5d20ba0b64736f6c63430008040033"

        contract_creation_code =
          "0x608060405260006005553480156200001657600080fd5b50604051620024e6380380620024e68339810160408190526200003991620003e5565b600080546001600160a01b0319166001600160a01b038816908117909155620000cf5760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527f69646765206461746120636f6e74726163742e0000000000000000000000000060648201526084015b60405180910390fd5b600380546001600160a01b0319166001600160a01b038716908117909155620001615760405162461bcd60e51b815260206004820152603860248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20736860448201527f697070696e67206d616e6167657220636f6e74726163742e00000000000000006064820152608401620000c6565b600180546001600160a01b0319166001600160a01b038616908117909155620001e25760405162461bcd60e51b81526020600482015260376024820152600080516020620024c683398151915260448201527f7970746f7374616d7020332e3120636f6e74726163742e0000000000000000006064820152608401620000c6565b600280546001600160a01b0319166001600160a01b038516908117909155620002635760405162461bcd60e51b815260206004820152603f6024820152600080516020620024c683398151915260448201527f7970746f7374616d7020332e312050726573616c6520636f6e74726163742e006064820152608401620000c6565b600482905581620002c55760405162461bcd60e51b815260206004820152602560248201527f596f75206e65656420746f2070726f766964652061206e6f6e2d7a65726f20706044820152643934b1b29760d91b6064820152608401620000c6565b805160049081146200032f5760405162461bcd60e51b815260206004820152602c60248201527f4e65656420636f727265637420616d6f756e74206f6620746f6b656e20706f6f60448201526b361030b2323932b9b9b2b99760a11b6064820152608401620000c6565b60005b81811015620003ba578281815181106200035c57634e487b7160e01b600052603260045260246000fd5b6020026020010151600682600481106200038657634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b039290921691909117905580620003b1816200050f565b91505062000332565b50505050505050506200054d565b80516001600160a01b0381168114620003e057600080fd5b919050565b60008060008060008060c08789031215620003fe578182fd5b6200040987620003c8565b955060206200041a818901620003c8565b95506200042a60408901620003c8565b94506200043a60608901620003c8565b608089015160a08a015191955093506001600160401b03808211156200045e578384fd5b818a0191508a601f83011262000472578384fd5b81518181111562000487576200048762000537565b8060051b604051601f19603f83011681018181108582111715620004af57620004af62000537565b604052828152858101935084860182860187018f1015620004ce578788fd5b8795505b83861015620004fb57620004e681620003c8565b855260019590950194938601938601620004d2565b508096505050505050509295509295509295565b60006000198214156200053057634e487b7160e01b81526011600452602481fd5b5060010190565b634e487b7160e01b600052604160045260246000fd5b611f69806200055d6000396000f3fe6080604052600436106101135760003560e01c8063759bd1fe116100a0578063a97eaba711610064578063a97eaba7146102db578063b7ec2086146102f1578063c7802ba214610306578063dd48f77414610326578063e2fa9ee01461034657600080fd5b8063759bd1fe146102535780638e8fa11f1461026657806390ffb8641461028657806391b7f5ed146102a65780639b6dbc8a146102c657600080fd5b80634707d000116100e75780634707d000146101c357806347535d7b146101e55780634a1bb6b41461020a57806353cdef02146102205780636aa7c1ab1461024057600080fd5b8062c0f916146101185780632481bb5c146101555780632ae3dc741461017557806339c4576214610195575b600080fd5b34801561012457600080fd5b50610138610133366004611be4565b610366565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561016157600080fd5b50600054610138906001600160a01b031681565b34801561018157600080fd5b50610138610190366004611a62565b610386565b3480156101a157600080fd5b506101b56101b0366004611a62565b6103f6565b60405190815260200161014c565b3480156101cf57600080fd5b506101e36101de366004611aca565b610492565b005b3480156101f157600080fd5b506101fa61064d565b604051901515815260200161014c565b34801561021657600080fd5b506101b560045481565b34801561022c57600080fd5b506101e361023b366004611aae565b610667565b6101e361024e36600461197b565b6107e2565b6101e3610261366004611b02565b610ad5565b34801561027257600080fd5b506101e36102813660046119f3565b610b11565b34801561029257600080fd5b506101fa6102a1366004611a62565b610c95565b3480156102b257600080fd5b506101e36102c1366004611be4565b610ca9565b3480156102d257600080fd5b506101e3610df6565b3480156102e757600080fd5b506101b560055481565b3480156102fd57600080fd5b506101b5610ed4565b34801561031257600080fd5b506101e3610321366004611b63565b610ff8565b34801561033257600080fd5b506101e3610341366004611aca565b6113d1565b34801561035257600080fd5b506101e3610361366004611be4565b6114e5565b6006816004811061037657600080fd5b01546001600160a01b0316905081565b600060068260018111156103aa57634e487b7160e01b600052602160045260246000fd5b846103b65760006103b9565b60025b60ff166103c69190611e6e565b600481106103e457634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03169392505050565b6001546000906001600160a01b03166370a082316104148585610386565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561045357600080fd5b505afa158015610467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048b9190611a96565b9392505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906104c090600401611ce8565b60206040518083038186803b1580156104d857600080fd5b505afa1580156104ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610510919061195f565b6001600160a01b0316336001600160a01b0316146105495760405162461bcd60e51b815260040161054090611da8565b60405180910390fd5b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a082319060240160206040518083038186803b15801561059257600080fd5b505afa1580156105a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca9190611a96565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561061057600080fd5b505af1158015610624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106489190611a46565b505050565b60008060055411801561066257506005544210155b905090565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061069590600401611dfe565b60206040518083038186803b1580156106ad57600080fd5b505afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e5919061195f565b6001600160a01b0316336001600160a01b0316146107155760405162461bcd60e51b815260040161054090611e23565b6001600160a01b0381166107875760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f2070726f7669646520616e2061637475616c20627260448201527234b233b2903230ba309031b7b73a3930b1ba1760691b6064820152608401610540565b600080546040516001600160a01b03808516939216917f6a6e057f21cc834cf349d8150e92867f52cb34d54375f174c09c431538c3dfb991a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6107ea61064d565b151560011461080b5760405162461bcd60e51b815260040161054090611d5d565b826108585760405162461bcd60e51b815260206004820152601d60248201527f596f75206e65656420746f2061636365707420746865207465726d732e0000006044820152606401610540565b806108755760405162461bcd60e51b815260040161054090611d18565b6000806108828287610386565b6001546040516370a0823160e01b81526001600160a01b038084166004830152929350600092909116906370a082319060240160206040518083038186803b1580156108cd57600080fd5b505afa1580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190611a96565b9050600081116109575760405162461bcd60e51b815260206004820181905260248201527f5468652072657175657374656420617373657420697320736f6c64206f75742e6044820152606401610540565b6000610961610ed4565b9050803410156109ca5760405162461bcd60e51b815260206004820152602e60248201527f53656e6420656e6f7567682063757272656e637920746f20706179206174206c60448201526d32b0b9ba1037b7329034ba32b69760911b6064820152608401610540565b60006109d68234611e86565b9050828111156109e35750815b60006109ef8383611ea6565b9050610a008b8b84898989896115ce565b60005460405163bf40fac160e01b815260206004820152600b60248201526a62656e656669636961727960a81b6044820152610aac9183916001600160a01b039091169063bf40fac19060640160206040518083038186803b158015610a6557600080fd5b505afa158015610a79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9d919061195f565b6001600160a01b0316906117eb565b80341115610ac857610ac8610ac18234611ec5565b33906117eb565b5050505050505050505050565b610add61064d565b1515600114610afe5760405162461bcd60e51b815260040161054090611d5d565b610b0b33858585856107e2565b50505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610b3f90600401611ce8565b60206040518083038186803b158015610b5757600080fd5b505afa158015610b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8f919061195f565b6001600160a01b0316336001600160a01b031614610bbf5760405162461bcd60e51b815260040161054090611da8565b6001600160a01b038316610c155760405162461bcd60e51b815260206004820152601e60248201527f6e65656420612076616c696420726576657273652072656769737472617200006044820152606401610540565b60405163c47f002760e01b81526001600160a01b0384169063c47f002790610c439085908590600401611cb9565b602060405180830381600087803b158015610c5d57600080fd5b505af1158015610c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0b9190611a96565b6000610ca183836103f6565b159392505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610cd790600401611dfe565b60206040518083038186803b158015610cef57600080fd5b505afa158015610d03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d27919061195f565b6001600160a01b0316336001600160a01b031614610d575760405162461bcd60e51b815260040161054090611e23565b60008111610db55760405162461bcd60e51b815260206004820152602560248201527f596f75206e65656420746f2070726f766964652061206e6f6e2d7a65726f20706044820152643934b1b29760d91b6064820152608401610540565b60045460408051918252602082018390527f8aa4fa52648a6d15edce8a179c792c86f3719d0cc3c572cf90f91948f0f2cb68910160405180910390a1600455565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190610e2490600401611dfe565b60206040518083038186803b158015610e3c57600080fd5b505afa158015610e50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e74919061195f565b6001600160a01b0316336001600160a01b031614610ea45760405162461bcd60e51b815260040161054090611e23565b600060058190556040517f589bfff7e7b59e33b97fa923dbc99256a6d2fdf9a631b431fa2dc06f4eea0ded9190a1565b6000805460405163bf40fac160e01b81526020600482015260066024820152654f7261636c6560d01b60448201526064916001600160a01b03169063bf40fac190830160206040518083038186803b158015610f2f57600080fd5b505afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f67919061195f565b60405163048cc1a760e51b8152600060048201526001600160a01b03919091169063919834e09060240160206040518083038186803b158015610fa957600080fd5b505afa158015610fbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe19190611a96565b600454610fee9190611ea6565b6106629190611e86565b61100061064d565b15156001146110215760405162461bcd60e51b815260040161054090611d5d565b8261106e5760405162461bcd60e51b815260206004820152601d60248201527f596f75206e65656420746f2061636365707420746865207465726d732e0000006044820152606401610540565b8061108b5760405162461bcd60e51b815260040161054090611d18565b6001600087828111156110ae57634e487b7160e01b600052602160045260246000fd5b905060006110bc838a610386565b6001546040516370a0823160e01b81526001600160a01b038084166004830152929350600092909116906370a082319060240160206040518083038186803b15801561110757600080fd5b505afa15801561111b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113f9190611a96565b9050808911156111a95760405162461bcd60e51b815260206004820152602f60248201527f4e6f7420656e6f7567682061737365747320617661696c61626c6520746f206260448201526e3abc903a3430ba1030b6b7bab73a1760891b6064820152608401610540565b600254604051627eeac760e11b8152336004820152602481018590528a916001600160a01b03169062fdd58e9060440160206040518083038186803b1580156111f157600080fd5b505afa158015611205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112299190611a96565b10156112ad5760405162461bcd60e51b815260206004820152604760248201527f596f75206e65656420746f206f776e20656e6f7567682070726573616c65207660448201527f6f75636865727320746f2072656465656d20746865207370656369666965642060648201526630b6b7bab73a1760c91b608482015260a401610540565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337019050509050848260008151811061131457634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508a8160008151811061134257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600254604051637507c42960e11b81526001600160a01b039091169063ea0f88529061138190339086908690600401611c36565b600060405180830381600087803b15801561139b57600080fd5b505af11580156113af573d6000803e3d6000fd5b505050506113c38a8d8d89888860006115ce565b505050505050505050505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906113ff90600401611ce8565b60206040518083038186803b15801561141757600080fd5b505afa15801561142b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144f919061195f565b6001600160a01b0316336001600160a01b03161461147f5760405162461bcd60e51b815260040161054090611da8565b60405163a22cb46560e01b81526001600160a01b0382811660048301526001602483015283169063a22cb46590604401600060405180830381600087803b1580156114c957600080fd5b505af11580156114dd573d6000803e3d6000fd5b505050505050565b60005460405163bf40fac160e01b81526001600160a01b039091169063bf40fac19061151390600401611dfe565b60206040518083038186803b15801561152b57600080fd5b505afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611563919061195f565b6001600160a01b0316336001600160a01b0316146115935760405162461bcd60e51b815260040161054090611e23565b60058190556040518181527f397a093f9e29b7327f453f9672278c54e4daed6b689ee9bb458ae76800452ad59060200160405180910390a150565b60005b858110156117e157600180546000916001600160a01b0390911690632f745c599087906115fe8689611ec5565b6116089190611ec5565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561164c57600080fd5b505afa158015611660573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116849190611a96565b600154604051632142170760e11b81526001600160a01b0388811660048301528c81166024830152604482018490529293509116906342842e0e90606401600060405180830381600087803b1580156116dc57600080fd5b505af11580156116f0573d6000803e3d6000fd5b505050508088600181111561171557634e487b7160e01b600052602160045260246000fd5b604080516001600160a01b038d168152891515602082015290810186905233907f1682a2a055cfda159fc278195b31d5f7ab61f5128c423fa0ea2bf511565a9b6d9060600160405180910390a46003546001805460405163ebaf492d60e01b81526001600160a01b039384169363ebaf492d9361179b9390911691869190600401611c76565b600060405180830381600087803b1580156117b557600080fd5b505af11580156117c9573d6000803e3d6000fd5b505050505080806117d990611edc565b9150506115d1565b5050505050505050565b8047101561183b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610540565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611888576040519150601f19603f3d011682016040523d82523d6000602084013e61188d565b606091505b50509050806106485760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610540565b80356002811061191357600080fd5b919050565b60008083601f840112611929578182fd5b50813567ffffffffffffffff811115611940578182fd5b60208301915083602082850101111561195857600080fd5b9250929050565b600060208284031215611970578081fd5b815161048b81611f0d565b600080600080600060808688031215611992578081fd5b853561199d81611f0d565b94506119ab60208701611904565b935060408601356119bb81611f25565b9250606086013567ffffffffffffffff8111156119d6578182fd5b6119e288828901611918565b969995985093965092949392505050565b600080600060408486031215611a07578283fd5b8335611a1281611f0d565b9250602084013567ffffffffffffffff811115611a2d578283fd5b611a3986828701611918565b9497909650939450505050565b600060208284031215611a57578081fd5b815161048b81611f25565b60008060408385031215611a74578182fd5b8235611a7f81611f25565b9150611a8d60208401611904565b90509250929050565b600060208284031215611aa7578081fd5b5051919050565b600060208284031215611abf578081fd5b813561048b81611f0d565b60008060408385031215611adc578182fd5b8235611ae781611f0d565b91506020830135611af781611f0d565b809150509250929050565b60008060008060608587031215611b17578384fd5b611b2085611904565b93506020850135611b3081611f25565b9250604085013567ffffffffffffffff811115611b4b578283fd5b611b5787828801611918565b95989497509550505050565b60008060008060008060a08789031215611b7b578081fd5b611b8487611904565b9550602087013594506040870135611b9b81611f0d565b93506060870135611bab81611f25565b9250608087013567ffffffffffffffff811115611bc6578182fd5b611bd289828a01611918565b979a9699509497509295939492505050565b600060208284031215611bf5578081fd5b5035919050565b6000815180845260208085019450808401835b83811015611c2b57815187529582019590820190600101611c0f565b509495945050505050565b6001600160a01b0384168152606060208201819052600090611c5a90830185611bfc565b8281036040840152611c6c8185611bfc565b9695505050505050565b6001600160a01b0384168152602081018390526060810160048310611cab57634e487b7160e01b600052602160045260246000fd5b826040830152949350505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6020808252601690820152751d1bdad95b905cdcda59db9b595b9d10dbdb9d1c9bdb60521b604082015260600190565b60208082526025908201527f596f75206e65656420746f2073656e642074686520616363657074616e6365206040820152643a32bc3a1760d91b606082015260800190565b6020808252602b908201527f546869732063616c6c206f6e6c7920776f726b73207768656e2074686520736860408201526a37b81034b99037b832b71760a91b606082015260800190565b60208082526036908201527f746f6b656e41737369676e6d656e74436f6e74726f6c206b65792072657175696040820152753932b2103337b9103a3434b990333ab731ba34b7b71760511b606082015260800190565b6020808252600b908201526a1cda1bdc10dbdb9d1c9bdb60aa1b604082015260600190565b6020808252602b908201527f73686f70436f6e74726f6c206b657920726571756972656420666f722074686960408201526a3990333ab731ba34b7b71760a91b606082015260800190565b60008219821115611e8157611e81611ef7565b500190565b600082611ea157634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611ec057611ec0611ef7565b500290565b600082821015611ed757611ed7611ef7565b500390565b6000600019821415611ef057611ef0611ef7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114611f2257600080fd5b50565b8015158114611f2257600080fdfea2646970667358221220f2e9ba9e74b25591261868f1d84c2beef56c6930ea91cecb35779eaf5d20ba0b64736f6c63430008040033596f75206e65656420746f2070726f7669646520616e2061637475616c2043720000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c500000000000000000000000065fa22ba3d2ae2fcace9aabd40ef4605fa6365680000000000000000000000003151b7dd9f6e806d2709153765925c373af470890000000000000000000000000e76fdd1c4dc5336c8a083f709fd415eaf32b9bf00000000000000000000000000000000000000000000000000000000000003de00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000008abc5ad351bf625b71b41872145a9f78df35bbd3000000000000000000000000f1044e94a41a4ce7a132755f041811aa11e2891f000000000000000000000000c52d7b6293d8f772f25db88fb44f9ecd1be5a7c8000000000000000000000000a5a1e60613312a15d327e6347389ceec4e173ba1"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.4+commit.c7e474f2",
          "evm_version" => "default",
          "name" => "CS3_1OnChainShop",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "0000000000000000000000000884fc15e31b1b634732e140cb3f94b3cbfdd1c500000000000000000000000065fa22ba3d2ae2fcace9aabd40ef4605fa6365680000000000000000000000003151b7dd9f6e806d2709153765925c373af470890000000000000000000000000e76fdd1c4dc5336c8a083f709fd415eaf32b9bf00000000000000000000000000000000000000000000000000000000000003de00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000008abc5ad351bf625b71b41872145a9f78df35bbd3000000000000000000000000f1044e94a41a4ce7a132755f041811aa11e2891f000000000000000000000000c52d7b6293d8f772f25db88fb44f9ecd1be5a7c8000000000000000000000000a5a1e60613312a15d327e6347389ceec4e173ba1"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end

      test "issue 5430, 5434" do
        contract_source_code = "contract C {function test() external pure returns (uint256) { return 1;} }"

        bytecode =
          "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063f8a8fd6d14602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60006001905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea164736f6c637823302e382e31342d63692e323032322e342e31332b636f6d6d69742e3235393233633166002b"

        contract_creation_code =
          "0x608060405234801561001057600080fd5b5060ae8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063f8a8fd6d14602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60006001905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea164736f6c637823302e382e31342d63692e323032322e342e31332b636f6d6d69742e3235393233633166002b"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.14-nightly.2022.4.13+commit.25923c1f",
          "evm_version" => "default",
          "name" => "C",
          "optimization" => false,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end

      test "issue 5431 (smart contract was compiled with bytecodeHash=none; constructor with arguments)" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_5431.sol"
          |> File.read!()

        bytecode =
          "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063893d20e81461003b578063a6f9dae114610059575b600080fd5b610043610075565b604051610050919061022a565b60405180910390f35b610073600480360381019061006e9190610276565b61009e565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461012c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012390610300565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610214826101e9565b9050919050565b61022481610209565b82525050565b600060208201905061023f600083018461021b565b92915050565b600080fd5b61025381610209565b811461025e57600080fd5b50565b6000813590506102708161024a565b92915050565b60006020828403121561028c5761028b610245565b5b600061029a84828501610261565b91505092915050565b600082825260208201905092915050565b7f43616c6c6572206973206e6f74206f776e657200000000000000000000000000600082015250565b60006102ea6013836102a3565b91506102f5826102b4565b602082019050919050565b60006020820190508181036000830152610319816102dd565b905091905056fea164736f6c6343000808000a"

        contract_creation_code =
          "0x608060405234801561001057600080fd5b506040516104e13803806104e183398181016040528101906100329190610165565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a350506101a5565b600080fd5b6000819050919050565b61010c816100f9565b811461011757600080fd5b50565b60008151905061012981610103565b92915050565b6000819050919050565b6101428161012f565b811461014d57600080fd5b50565b60008151905061015f81610139565b92915050565b6000806040838503121561017c5761017b6100f4565b5b600061018a8582860161011a565b925050602061019b85828601610150565b9150509250929050565b61032d806101b46000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063893d20e81461003b578063a6f9dae114610059575b600080fd5b610043610075565b604051610050919061022a565b60405180910390f35b610073600480360381019061006e9190610276565b61009e565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461012c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012390610300565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610214826101e9565b9050919050565b61022481610209565b82525050565b600060208201905061023f600083018461021b565b92915050565b600080fd5b61025381610209565b811461025e57600080fd5b50565b6000813590506102708161024a565b92915050565b60006020828403121561028c5761028b610245565b5b600061029a84828501610261565b91505092915050565b600082825260208201905092915050565b7f43616c6c6572206973206e6f74206f776e657200000000000000000000000000600082015250565b60006102ea6013836102a3565b91506102f5826102b4565b602082019050919050565b60006020820190508181036000830152610319816102dd565b905091905056fea164736f6c6343000808000afffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040000000000000000000000000000000000000000000000000000000000005886"

        contract_address = insert(:contract_address, contract_code: bytecode)

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.8+commit.dddeac2f",
          "evm_version" => "default",
          "name" => "Owner",
          "optimization" => false,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040000000000000000000000000000000000000000000000000000000000005886"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end
    end

    describe "cover new functionality from https://github.com/blockscout/blockscout/pull/5479" do
      test "return {:error, :no_creation_data} when there is no contract creation code" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_5431.sol"
          |> File.read!()

        bytecode =
          "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063893d20e81461003b578063a6f9dae114610059575b600080fd5b610043610075565b604051610050919061022a565b60405180910390f35b610073600480360381019061006e9190610276565b61009e565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461012c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012390610300565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610214826101e9565b9050919050565b61022481610209565b82525050565b600060208201905061023f600083018461021b565b92915050565b600080fd5b61025381610209565b811461025e57600080fd5b50565b6000813590506102708161024a565b92915050565b60006020828403121561028c5761028b610245565b5b600061029a84828501610261565b91505092915050565b600082825260208201905092915050565b7f43616c6c6572206973206e6f74206f776e657200000000000000000000000000600082015250565b60006102ea6013836102a3565b91506102f5826102b4565b602082019050919050565b60006020820190508181036000830152610319816102dd565b905091905056fea164736f6c6343000808000a"

        contract_address = insert(:contract_address, contract_code: bytecode)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.8+commit.dddeac2f",
          "evm_version" => "default",
          "name" => "Owner",
          "optimization" => false,
          "autodetect_constructor_args" => true
        }

        assert {:error, :no_creation_data} = Verifier.evaluate_authenticity(contract_address.hash, params)
      end

      test "return {:error, :deployed_bytecode}" do
        contract_source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/issue_5431.sol"
          |> File.read!()

        contract_creation_code =
          "0x608060405234801561001057600080fd5b506040516104e13803806104e183398181016040528101906100329190610165565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a350506101a5565b600080fd5b6000819050919050565b61010c816100f9565b811461011757600080fd5b50565b60008151905061012981610103565b92915050565b6000819050919050565b6101428161012f565b811461014d57600080fd5b50565b60008151905061015f81610139565b92915050565b6000806040838503121561017c5761017b6100f4565b5b600061018a8582860161011a565b925050602061019b85828601610150565b9150509250929050565b61032d806101b46000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063893d20e81461003b578063a6f9dae114610059575b600080fd5b610043610075565b604051610050919061022a565b60405180910390f35b610073600480360381019061006e9190610276565b61009e565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461012c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012390610300565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610214826101e9565b9050919050565b61022481610209565b82525050565b600060208201905061023f600083018461021b565b92915050565b600080fd5b61025381610209565b811461025e57600080fd5b50565b6000813590506102708161024a565b92915050565b60006020828403121561028c5761028b610245565b5b600061029a84828501610261565b91505092915050565b600082825260208201905092915050565b7f43616c6c6572206973206e6f74206f776e657200000000000000000000000000600082015250565b60006102ea6013836102a3565b91506102f5826102b4565b602082019050919050565b60006020820190508181036000830152610319816102dd565b905091905056fea164736f6c6343000808000afffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040000000000000000000000000000000000000000000000000000000000005886"

        contract_address = insert(:contract_address, contract_code: "0x")

        :transaction
        |> insert(
          created_contract_address_hash: contract_address.hash,
          input: contract_creation_code
        )
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => contract_source_code,
          "compiler_version" => "v0.8.8+commit.dddeac2f",
          "evm_version" => "default",
          "name" => "Owner",
          "optimization" => false,
          "autodetect_constructor_args" => true
        }

        assert {:error, :deployed_bytecode} = Verifier.evaluate_authenticity(contract_address.hash, params)
      end
    end

    describe "tests from constructor_arguments_test.exs" do
      test "verifies with require messages" do
        source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/home_bridge.sol"
          |> File.read!()

        constructor_arguments =
          "000000000000000000000000fb5a36f0e12cef9f88d95f0e02cad4ba183336dc0000000000000000000000000000000000000000000000000000000000000032"

        input =
          "608060405234801561001057600080fd5b50604051604080610c2e8339810180604052604081101561003057600080fd5b5080516020909101516001600160a01b038216610098576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610c0b6023913960400191505060405180910390fd5b60648111156100f2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180610bd76034913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b039390931692909217909155600255610ab2806101256000396000f3fe6080604052600436106100555760003560e01c806305dab2881461005a5780630b1ec76014610081578063236459c7146100b2578063397bc6411461010b578063b60d428814610135578063f176cde71461013f575b600080fd5b34801561006657600080fd5b5061006f610184565b60408051918252519081900360200190f35b34801561008d57600080fd5b5061009661018a565b604080516001600160a01b039092168252519081900360200190f35b3480156100be57600080fd5b506100f7600480360360808110156100d557600080fd5b50803590602081013590604081013590606001356001600160a01b0316610199565b604080519115158252519081900360200190f35b34801561011757600080fd5b506100f76004803603602081101561012e57600080fd5b50356103c7565b61013d6103df565b005b34801561014b57600080fd5b5061013d6004803603608081101561016257600080fd5b50803590602081013590604081013590606001356001600160a01b03166103e1565b60025481565b6001546001600160a01b031681565b60006001600160a01b0382166101e357604051600160e51b62461bcd028152600401808060200182810382526027815260200180610a3a6027913960400191505060405180910390fd5b6000831161023b5760408051600160e51b62461bcd02815260206004820152601760248201527f616d6f756e74206d757374206e6f74206265207a65726f000000000000000000604482015290519081900360640190fd5b60408051602080820188905281830187905260608083018790526001600160a01b038616901b608083015282516074818403018152609490920183528151918101919091206000818152918290529190206002015460ff16156102e85760408051600160e51b62461bcd02815260206004820152601a60248201527f7472616e7366657220616c726561647920636f6d706c65746564000000000000604482015290519081900360640190fd5b600081815260208190526040812060010190805b82548110156103b15760015483546001600160a01b039091169063facd743b9085908490811061032857fe5b600091825260209182902001546040805163ffffffff851660e01b81526001600160a01b0390921660048301525160248083019392829003018186803b15801561037157600080fd5b505afa158015610385573d6000803e3d6000fd5b505050506040513d602081101561039b57600080fd5b5051156103a9576001820191505b6001016102fc565b506103ba61070c565b1115979650505050505050565b60006020819052908152604090206002015460ff1681565b565b60408051602080820187905281830186905260608083018690526001600160a01b038516901b608083015282516074818403018152609490920183528151918101919091206000818152918290529190206002015460ff161561048e5760408051600160e51b62461bcd02815260206004820152601a60248201527f7472616e7366657220616c726561647920636f6d706c65746564000000000000604482015290519081900360640190fd5b60015460408051600160e01b63facd743b02815233600482015290516001600160a01b039092169163facd743b91602480820192602092909190829003018186803b1580156104dc57600080fd5b505afa1580156104f0573d6000803e3d6000fd5b505050506040513d602081101561050657600080fd5b505161054657604051600160e51b62461bcd028152600401808060200182810382526026815260200180610a616026913960400191505060405180910390fd5b6001600160a01b03821661058e57604051600160e51b62461bcd028152600401808060200182810382526027815260200180610a3a6027913960400191505060405180910390fd5b600083116105e65760408051600160e51b62461bcd02815260206004820152601760248201527f616d6f756e74206d757374206e6f74206265207a65726f000000000000000000604482015290519081900360640190fd5b6105f0813361079f565b156106485760408051868152602081018690528082018590526001600160a01b0384166060820152905133917fdee96a12459a8c17d4cf9571d9ab18de19fa1055adff514e2d25595382d218df919081900360800190a25b61065181610830565b1561070557600081815260208190526040812060028101805460ff19166001908117909155610682929101906109da565b6040516000906001600160a01b0384169085156108fc0290869084818181858888f1604080518c8152602081018c90528082018b90526001600160a01b038a166060820152821515608082015290519196507f546c8621785b0cc9f951c75b68621fbdfce93ba6df3943b1271813c3598852d1955081900360a0019350915050a1505b5050505050565b60006064600254600160009054906101000a90046001600160a01b03166001600160a01b031663d6832ea96040518163ffffffff1660e01b815260040160206040518083038186803b15801561076157600080fd5b505afa158015610775573d6000803e3d6000fd5b505050506040513d602081101561078b57600080fd5b5051026063018161079857fe5b0490505b90565b6000828152602081815260408083206001600160a01b038516845290915281205460ff16156107d05750600061082a565b506000828152602081815260408083206001600160a01b038516808552818452918420805460ff19166001908117909155848452908101805480830182559085529290932090910180546001600160a01b03191690911790555b92915050565b60008061083b61070c565b600084815260208190526040902060010154909150811115610861576000915050610893565b61086a83610898565b60008381526020819052604090206001015481111561088d576000915050610893565b60019150505b919050565b6000818152602081905260408120600101905b81548110156109d55760015482546001600160a01b039091169063facd743b908490849081106108d757fe5b600091825260209182902001546040805163ffffffff851660e01b81526001600160a01b0390921660048301525160248083019392829003018186803b15801561092057600080fd5b505afa158015610934573d6000803e3d6000fd5b505050506040513d602081101561094a57600080fd5b505115610959576001016109d0565b81548290600019810190811061096b57fe5b9060005260206000200160009054906101000a90046001600160a01b031682828154811061099557fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905581546109ce8360001983016109fb565b505b6108ab565b505050565b50805460008255906000526020600020908101906109f89190610a1b565b50565b8154818355818111156109d5576000838152602090206109d59181019083015b61079c91905b80821115610a355760008155600101610a21565b509056fe726563697069656e74206d757374206e6f7420626520746865207a65726f2061646472657373216d7573742062652076616c696461746f7220746f20636f6e6669726d207472616e7366657273a165627a7a7230582034f1dd7d09db2ab8295f85e72b0543ef67ff431b2d624264cea6c7a9ce4e1f1900295f76616c696461746f7273526571756972656450657263656e74206d757374206265206265747765656e203020616e642031303070726f7879206d757374206e6f7420626520746865207a65726f206164647265737321000000000000000000000000fb5a36f0e12cef9f88d95f0e02cad4ba183336dc0000000000000000000000000000000000000000000000000000000000000032"

        deployed_bytecode =
          "0x6080604052600436106100555760003560e01c806305dab2881461005a5780630b1ec76014610081578063236459c7146100b2578063397bc6411461010b578063b60d428814610135578063f176cde71461013f575b600080fd5b34801561006657600080fd5b5061006f610184565b60408051918252519081900360200190f35b34801561008d57600080fd5b5061009661018a565b604080516001600160a01b039092168252519081900360200190f35b3480156100be57600080fd5b506100f7600480360360808110156100d557600080fd5b50803590602081013590604081013590606001356001600160a01b0316610199565b604080519115158252519081900360200190f35b34801561011757600080fd5b506100f76004803603602081101561012e57600080fd5b50356103c7565b61013d6103df565b005b34801561014b57600080fd5b5061013d6004803603608081101561016257600080fd5b50803590602081013590604081013590606001356001600160a01b03166103e1565b60025481565b6001546001600160a01b031681565b60006001600160a01b0382166101e357604051600160e51b62461bcd028152600401808060200182810382526027815260200180610a3a6027913960400191505060405180910390fd5b6000831161023b5760408051600160e51b62461bcd02815260206004820152601760248201527f616d6f756e74206d757374206e6f74206265207a65726f000000000000000000604482015290519081900360640190fd5b60408051602080820188905281830187905260608083018790526001600160a01b038616901b608083015282516074818403018152609490920183528151918101919091206000818152918290529190206002015460ff16156102e85760408051600160e51b62461bcd02815260206004820152601a60248201527f7472616e7366657220616c726561647920636f6d706c65746564000000000000604482015290519081900360640190fd5b600081815260208190526040812060010190805b82548110156103b15760015483546001600160a01b039091169063facd743b9085908490811061032857fe5b600091825260209182902001546040805163ffffffff851660e01b81526001600160a01b0390921660048301525160248083019392829003018186803b15801561037157600080fd5b505afa158015610385573d6000803e3d6000fd5b505050506040513d602081101561039b57600080fd5b5051156103a9576001820191505b6001016102fc565b506103ba61070c565b1115979650505050505050565b60006020819052908152604090206002015460ff1681565b565b60408051602080820187905281830186905260608083018690526001600160a01b038516901b608083015282516074818403018152609490920183528151918101919091206000818152918290529190206002015460ff161561048e5760408051600160e51b62461bcd02815260206004820152601a60248201527f7472616e7366657220616c726561647920636f6d706c65746564000000000000604482015290519081900360640190fd5b60015460408051600160e01b63facd743b02815233600482015290516001600160a01b039092169163facd743b91602480820192602092909190829003018186803b1580156104dc57600080fd5b505afa1580156104f0573d6000803e3d6000fd5b505050506040513d602081101561050657600080fd5b505161054657604051600160e51b62461bcd028152600401808060200182810382526026815260200180610a616026913960400191505060405180910390fd5b6001600160a01b03821661058e57604051600160e51b62461bcd028152600401808060200182810382526027815260200180610a3a6027913960400191505060405180910390fd5b600083116105e65760408051600160e51b62461bcd02815260206004820152601760248201527f616d6f756e74206d757374206e6f74206265207a65726f000000000000000000604482015290519081900360640190fd5b6105f0813361079f565b156106485760408051868152602081018690528082018590526001600160a01b0384166060820152905133917fdee96a12459a8c17d4cf9571d9ab18de19fa1055adff514e2d25595382d218df919081900360800190a25b61065181610830565b1561070557600081815260208190526040812060028101805460ff19166001908117909155610682929101906109da565b6040516000906001600160a01b0384169085156108fc0290869084818181858888f1604080518c8152602081018c90528082018b90526001600160a01b038a166060820152821515608082015290519196507f546c8621785b0cc9f951c75b68621fbdfce93ba6df3943b1271813c3598852d1955081900360a0019350915050a1505b5050505050565b60006064600254600160009054906101000a90046001600160a01b03166001600160a01b031663d6832ea96040518163ffffffff1660e01b815260040160206040518083038186803b15801561076157600080fd5b505afa158015610775573d6000803e3d6000fd5b505050506040513d602081101561078b57600080fd5b5051026063018161079857fe5b0490505b90565b6000828152602081815260408083206001600160a01b038516845290915281205460ff16156107d05750600061082a565b506000828152602081815260408083206001600160a01b038516808552818452918420805460ff19166001908117909155848452908101805480830182559085529290932090910180546001600160a01b03191690911790555b92915050565b60008061083b61070c565b600084815260208190526040902060010154909150811115610861576000915050610893565b61086a83610898565b60008381526020819052604090206001015481111561088d576000915050610893565b60019150505b919050565b6000818152602081905260408120600101905b81548110156109d55760015482546001600160a01b039091169063facd743b908490849081106108d757fe5b600091825260209182902001546040805163ffffffff851660e01b81526001600160a01b0390921660048301525160248083019392829003018186803b15801561092057600080fd5b505afa158015610934573d6000803e3d6000fd5b505050506040513d602081101561094a57600080fd5b505115610959576001016109d0565b81548290600019810190811061096b57fe5b9060005260206000200160009054906101000a90046001600160a01b031682828154811061099557fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905581546109ce8360001983016109fb565b505b6108ab565b505050565b50805460008255906000526020600020908101906109f89190610a1b565b50565b8154818355818111156109d5576000838152602090206109d59181019083015b61079c91905b80821115610a355760008155600101610a21565b509056fe726563697069656e74206d757374206e6f7420626520746865207a65726f2061646472657373216d7573742062652076616c696461746f7220746f20636f6e6669726d207472616e7366657273a165627a7a7230582034f1dd7d09db2ab8295f85e72b0543ef67ff431b2d624264cea6c7a9ce4e1f190029"

        contract_address = insert(:contract_address, contract_code: deployed_bytecode)

        input_data = %Data{
          bytes: Base.decode16!(input, case: :lower)
        }

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: input_data)
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => source_code,
          "compiler_version" => "v0.5.8+commit.23d335f2",
          "evm_version" => "default",
          "name" => "HomeBridge",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments: ^constructor_arguments
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end

      test "verifies with string in keccak256" do
        source_code =
          "#{File.cwd!()}/test/support/fixture/smart_contract/ERC677.sol"
          |> File.read!()

        input =
          "60806040523480156200001157600080fd5b5060405162002f3f38038062002f3f833981810160405260a08110156200003757600080fd5b8101908080516401000000008111156200005057600080fd5b820160208101848111156200006457600080fd5b81516401000000008111828201871017156200007f57600080fd5b505092919060200180516401000000008111156200009c57600080fd5b82016020810184811115620000b057600080fd5b8151640100000000811182820187101715620000cb57600080fd5b50506020820151604080840151606090940151600080546001600160a01b031916331780825592519497509295509287928792879287928792879287926012928592859285926001600160a01b0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38251620001559060049060208601906200058d565b5081516200016b9060059060208501906200058d565b506006805460ff191660ff92909216919091179055505060405180605262002eed8239604080519182900360520182208651602097880120838301835260018085527f310000000000000000000000000000000000000000000000000000000000000094890194909452825180890192909252818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101929092523060a0808401919091528151808403909101815260c090920190528051908501206007555062000257926001600160a01b038716925062001e46620003ec821b17901c9050565b80156200027e57506200027e826001600160a01b0316620003ec60201b62001e461760201c565b8015620002a55750620002a5816001600160a01b0316620003ec60201b62001e461760201c565b6200031157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f74206120636f6e7472616374206164647265737300000000000000000000604482015290519081900360640190fd5b607b6200032884826001600160e01b03620003f216565b600a80546001600160a01b038087166001600160a01b03199283168117909355600b8054878316908416179055600c8054918616919092161790556040805183815290517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968859181900360200190a250506001600160a01b036000819052600d6020527fa934977eb9828ba1f50591af02c98441645b4f0e916e0fecb4cc8e9c633dade280546001600160a01b03191690911790555062000632975050505050505050565b3b151590565b6001600160a01b0382166200046857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b62000484816003546200051160201b62001de51790919060201c565b6003556001600160a01b038216600090815260016020908152604090912054620004b991839062001de562000511821b17901c565b6001600160a01b03831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000828201838110156200058657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005d057805160ff191683800117855562000600565b8280016001018555821562000600579182015b8281111562000600578251825591602001919060010190620005e3565b506200060e92915062000612565b5090565b6200062f91905b808211156200060e576000815560010162000619565b90565b6128ab80620006426000396000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c8063726600ce11610130578063a457c2d7116100b8578063dd62ed3e1161007c578063dd62ed3e1461075f578063f2d5d56b1461078d578063f2fde38b146107b9578063fbb2a53f146107df578063ff9e884d146107e757610232565b8063a457c2d71461069d578063a9059cbb146106c9578063b753a98c146106f5578063bb35783b14610721578063c794c7691461075757610232565b80638f32d59b116100ff5780638f32d59b146105b55780638fcbaf0c146105bd57806395d89b41146106175780639712fdf81461061f5780639da38e2f1461064557610232565b8063726600ce146105595780637a13685a1461057f5780637ecebe00146105875780638da5cb5b146105ad57610232565b806337fb7e21116101be57806354fd4d501161018257806354fd4d50146104ed57806369ffa08a146104f55780636e15d21b1461052357806370a082311461052b578063715018a61461055157610232565b806337fb7e21146103c657806339509351146103ea5780634000aea01461041657806340c10f191461049b5780634bcb88bc146104c757610232565b8063238a3fe111610205578063238a3fe11461033657806323b872dd1461036257806330adf81f14610398578063313ce567146103a05780633644e515146103be57610232565b806304df017d1461023757806306fdde031461025f578063095ea7b3146102dc57806318160ddd1461031c575b600080fd5b61025d6004803603602081101561024d57600080fd5b50356001600160a01b0316610815565b005b610267610a56565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a1578181015183820152602001610289565b50505050905090810190601f1680156102ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610308600480360360408110156102f257600080fd5b506001600160a01b038135169060200135610aec565b604080519115158252519081900360200190f35b610324610b02565b60408051918252519081900360200190f35b6103086004803603604081101561034c57600080fd5b506001600160a01b038135169060200135610b08565b6103086004803603606081101561037857600080fd5b506001600160a01b03813581169160208101359091169060400135610b8d565b610324610baf565b6103a8610bd3565b6040805160ff9092168252519081900360200190f35b610324610bdc565b6103ce610be2565b604080516001600160a01b039092168252519081900360200190f35b6103086004803603604081101561040057600080fd5b506001600160a01b038135169060200135610bf1565b6103086004803603606081101561042c57600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561045c57600080fd5b82018360208201111561046e57600080fd5b8035906020019184600183028401116401000000008311171561049057600080fd5b509092509050610c32565b610308600480360360408110156104b157600080fd5b506001600160a01b038135169060200135610dd2565b6103ce600480360360208110156104dd57600080fd5b50356001600160a01b0316610e80565b610267610e9b565b61025d6004803603604081101561050b57600080fd5b506001600160a01b0381358116916020013516610eb8565b6103ce611083565b6103246004803603602081101561054157600080fd5b50356001600160a01b0316611092565b61025d6110ad565b6103086004803603602081101561056f57600080fd5b50356001600160a01b0316611133565b6103ce61116d565b6103246004803603602081101561059d57600080fd5b50356001600160a01b031661117c565b6103ce61118e565b61030861119d565b61025d60048036036101008110156105d457600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608081013515159060ff60a0820135169060c08101359060e001356111ae565b610267611446565b61025d6004803603602081101561063557600080fd5b50356001600160a01b03166114a7565b61064d6116e6565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610689578181015183820152602001610671565b505050509050019250505060405180910390f35b610308600480360360408110156106b357600080fd5b506001600160a01b03813516906020013561182a565b610308600480360360408110156106df57600080fd5b506001600160a01b038135169060200135611866565b61025d6004803603604081101561070b57600080fd5b506001600160a01b03813516906020013561187d565b61025d6004803603606081101561073757600080fd5b506001600160a01b03813581169160208101359091169060400135611888565b6103ce611899565b6103246004803603604081101561077557600080fd5b506001600160a01b03813581169160200135166118a4565b61025d600480360360408110156107a357600080fd5b506001600160a01b0381351690602001356118cf565b61025d600480360360208110156107cf57600080fd5b50356001600160a01b03166118da565b61032461192d565b610324600480360360408110156107fd57600080fd5b506001600160a01b0381358116916020013516611933565b61081d61119d565b61085c576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b61086581611133565b6108ad576040805162461bcd60e51b8152602060048201526014602482015273189c9a5919d9481a5cdb89dd08195e1a5cdd195960621b604482015290519081900360640190fd5b6001600160a01b038082166000908152600d6020526040812054908290526000805160206126cb833981519152549082169190811680610929576040805162461bcd60e51b81526020600482015260126024820152711e995c9bc81859191c995cdcc8199bdd5b9960721b604482015290519081900360640190fd5b836001600160a01b0316816001600160a01b0316146109c8576001600160a01b038082166000908152600d602052604090205491925090811690811480159061097a57506001600160a01b03811615155b6109c3576040805162461bcd60e51b81526020600482015260156024820152741a5b9d985b1a59081859191c995cdcc8199bdd5b99605a1b604482015290519081900360640190fd5b610929565b6001600160a01b038083166000908152600d602052604080822080548488166001600160a01b0319918216179091559287168252902080549091169055600e54610a1990600163ffffffff61195016565b600e556040516001600160a01b038516907f5d9d5034656cb3ebfb0655057cd7f9b4077a9b42ff42ce223cbac5bc586d212690600090a250505050565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ae25780601f10610ab757610100808354040283529160200191610ae2565b820191906000526020600020905b815481529060010190602001808311610ac557829003601f168201915b5050505050905090565b6000610af93384846119ad565b50600192915050565b60035490565b600a546000906001600160a01b0316331480610b2e5750600b546001600160a01b031633145b80610b435750600c546001600160a01b031633145b610b83576040805162461bcd60e51b815260206004820152600c60248201526b3bb937b7339039b2b73232b960a11b604482015290519081900360640190fd5b610af98383611a99565b6000610b9a848484611bd9565b610ba5848484611c2c565b5060019392505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b60065460ff1690565b60075481565b600a546001600160a01b031681565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610af9918590610c2d908663ffffffff611de516565b6119ad565b6000846001600160a01b03811615801590610c5657506001600160a01b0381163014155b610c9f576040805162461bcd60e51b81526020600482015260156024820152741b9bdd0818481d985b1a59081c9958da5c1a595b9d605a1b604482015290519081900360640190fd5b610ca98686611a99565b856001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1687878760405180848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a3610d37866001600160a01b0316611e46565b15610dc657610d7e33878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e4c92505050565b610dc6576040805162461bcd60e51b815260206004820152601460248201527318dbdb9d1c9858dd0818d85b1b0819985a5b195960621b604482015290519081900360640190fd5b50600195945050505050565b6000610ddd33611133565b610e2e576040805162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206272696467650000000000000000604482015290519081900360640190fd5b610e388383612039565b6040805183815290516001600160a01b038516917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885919081900360200190a250600192915050565b600d602052600090815260409020546001600160a01b031681565b604051806040016040528060018152602001603160f81b81525081565b610ec061119d565b610eff576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b806001600160a01b03811615801590610f2157506001600160a01b0381163014155b610f6a576040805162461bcd60e51b81526020600482015260156024820152741b9bdd0818481d985b1a59081c9958da5c1a595b9d605a1b604482015290519081900360640190fd5b6001600160a01b038316610fe8576040513031906001600160a01b0384169082156108fc029083906000818181858888f19350505050610fe2578083604051610fb290612621565b6001600160a01b039091168152604051908190036020019082f080158015610fde573d6000803e3d6000fd5b5050505b5061107e565b604080516370a0823160e01b8152306004820152905184916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561103357600080fd5b505afa158015611047573d6000803e3d6000fd5b505050506040513d602081101561105d57600080fd5b5051905061107b6001600160a01b038316858363ffffffff61212b16565b50505b505050565b600c546001600160a01b031681565b6001600160a01b031660009081526001602052604090205490565b6110b561119d565b6110f4576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152600f60248201526e1b9bdd081a5b5c1b195b595b9d1959608a1b604482015290519081900360640190fd5b60006001600160a01b038281161480159061116757506001600160a01b038281166000908152600d60205260409020541615155b92915050565b600b546001600160a01b031681565b60086020526000908152604090205481565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b8415806111c25750846111bf61217d565b11155b611204576040805162461bcd60e51b815260206004820152600e60248201526d696e76616c69642065787069727960901b604482015290519081900360640190fd5b600754604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020808301919091526001600160a01b03808d16838501528b166060830152608082018a905260a0820189905287151560c0808401919091528351808403909101815260e08301845280519082012061190160f01b610100840152610102830194909452610122808301949094528251808303909401845261014282018084528451948201949094206000909452610162820180845284905260ff87166101828301526101a282018690526101c2820185905291516001926101e2808401939192601f1981019281900390910190855afa15801561130e573d6000803e3d6000fd5b505050602060405103516001600160a01b0316896001600160a01b03161461137d576040805162461bcd60e51b815260206004820152601f60248201527f696e76616c6964207369676e6174757265206f7220706172616d657465727300604482015290519081900360640190fd5b6001600160a01b038916600090815260086020526040902080546001810190915587146113e1576040805162461bcd60e51b815260206004820152600d60248201526c696e76616c6964206e6f6e636560981b604482015290519081900360640190fd5b6000856113ef5760006113f3565b6000195b90506114008a8a836119ad565b8561140c57600061140e565b865b6001600160a01b039a8b1660009081526009602090815260408083209c909d1682529a909a5299909820989098555050505050505050565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ae25780601f10610ab757610100808354040283529160200191610ae2565b6114af61119d565b6114ee576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b6032600e541061152f5760405162461bcd60e51b81526004018080602001828103825260288152602001806127816028913960400191505060405180910390fd5b611541816001600160a01b0316611e46565b61158b576040805162461bcd60e51b81526020600482015260166024820152756e6f74206120636f6e7472616374206164647265737360501b604482015290519081900360640190fd5b61159481611133565b156115de576040805162461bcd60e51b815260206004820152601560248201527462726964676520616c72656164792065786973747360581b604482015290519081900360640190fd5b6001600160a01b036000819052600d6020526000805160206126cb833981519152541680611653576040805162461bcd60e51b815260206004820152601c60248201527f666972737420627269646765206973207a65726f206164647265737300000000604482015290519081900360640190fd5b600d6020526000805160206126cb83398151915280546001600160a01b03199081166001600160a01b038581169182179093556000908152604090208054909116918316919091179055600e546116ab906001611de5565b600e556040516001600160a01b038316907f3cda433c5679ae4c6a5dea50840e222a42cba3695e4663de4366be899348422190600090a25050565b606080600e54604051908082528060200260200182016040528015611715578160200160208202803883390190505b506001600160a01b036000818152600d6020526000805160206126cb83398151915254929350911680611784576040805162461bcd60e51b81526020600482015260126024820152711e995c9bc81859191c995cdcc8199bdd5b9960721b604482015290519081900360640190fd5b6001600160a01b038181161461182257808383815181106117a157fe5b6001600160a01b039283166020918202929092018101919091529181166000908152600d90925260409091205460019290920191168061181d576040805162461bcd60e51b81526020600482015260126024820152711e995c9bc81859191c995cdcc8199bdd5b9960721b604482015290519081900360640190fd5b611784565b509091505090565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610af9918590610c2d908663ffffffff61195016565b60006118728383611a99565b610af9338484611c2c565b61107e338383610b8d565b611893838383610b8d565b50505050565b6001600160a01b0381565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b61107e823383610b8d565b6118e261119d565b611921576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b61192a81612181565b50565b600e5481565b600960209081526000928352604080842090915290825290205481565b6000828211156119a7576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6001600160a01b0383166119f25760405162461bcd60e51b81526004018080602001828103825260248152602001806127ce6024913960400191505060405180910390fd5b6001600160a01b038216611a375760405162461bcd60e51b81526004018080602001828103825260228152602001806126a96022913960400191505060405180910390fd5b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600a546000906001600160a01b0316331480611abf5750600b546001600160a01b031633145b80611ad45750600c546001600160a01b031633145b15611b885733600090815260016020526040902054611af9908363ffffffff61195016565b33600090815260016020526040808220929092556001600160a01b03851681522054611b2b908363ffffffff611de516565b6001600160a01b0384166000818152600160209081526040918290209390935580518581529051919233927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001611b95565b611b928383612221565b90505b8061107e576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6000611be684848461222e565b905080611893576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b611c3e826001600160a01b0316611e46565b8015611c655750604080516000815260208101909152611c6390849084908490611e4c565b155b1561107e57611c7382611133565b15611caf5760405162461bcd60e51b81526004018080602001828103825260258152602001806127166025913960400191505060405180910390fd5b600a546001600160a01b0383811691161415611cfc5760405162461bcd60e51b815260040180806020018281038252602b8152602001806126eb602b913960400191505060405180910390fd5b600b546001600160a01b0383811691161415611d495760405162461bcd60e51b815260040180806020018281038252602e815260200180612849602e913960400191505060405180910390fd5b600c546001600160a01b0383811691161415611d965760405162461bcd60e51b815260040180806020018281038252602d81526020018061281c602d913960400191505060405180910390fd5b604080516001600160a01b0380861682528416602082015280820183905290517f11249f0fc79fc134a15a10d1da8291b79515bf987e036ced05b9ec119614070b9181900360600190a1505050565b600082820183811015611e3f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b3b151590565b6000606060405180606001604052806026815260200161275b6026913990506000856001600160a01b03168288878760405160240180846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611ed9578181015183820152602001611ec1565b50505050905090810190601f168015611f065780820380516001836020036101000a031916815260200191505b50945050505050604051602081830303815290604052906040518082805190602001908083835b60208310611f4c5780518252601f199092019160209182019101611f2d565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932092860180516001600160e01b03166001600160e01b031990941693909317835251855190945084935090508083835b60208310611fc45780518252601f199092019160209182019101611fa5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612026576040519150601f19603f3d011682016040523d82523d6000602084013e61202b565b606091505b509098975050505050505050565b6001600160a01b038216612094576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6003546120a7908263ffffffff611de516565b6003556001600160a01b0382166000908152600160205260409020546120d3908263ffffffff611de516565b6001600160a01b03831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261107e908490612325565b4290565b6001600160a01b0381166121c65760405162461bcd60e51b81526004018080602001828103825260268152602001806126836026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610af93384846124dd565b600061223b8484846124dd565b6001600160a01b0384163314610ba557600061225785336118a4565b9050600019811461227c576122778533610c2d848763ffffffff61195016565b61231f565b6001600160a01b038516600090815260096020908152604080832033845290915290205415806122d657506122af61217d565b6001600160a01b038616600090815260096020908152604080832033845290915290205410155b61231f576040805162461bcd60e51b8152602060048201526015602482015274195e1c1a5c9e481a5cc81a5b881d1a19481c185cdd605a1b604482015290519081900360640190fd5b50610ba5565b612337826001600160a01b0316611e46565b612388576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106123c65780518252601f1990920191602091820191016123a7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612428576040519150601f19603f3d011682016040523d82523d6000602084013e61242d565b606091505b509150915081612484576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611893578080602001905160208110156124a057600080fd5b50516118935760405162461bcd60e51b815260040180806020018281038252602a8152602001806127f2602a913960400191505060405180910390fd5b6001600160a01b0383166125225760405162461bcd60e51b81526004018080602001828103825260258152602001806127a96025913960400191505060405180910390fd5b6001600160a01b0382166125675760405162461bcd60e51b81526004018080602001828103825260238152602001806126606023913960400191505060405180910390fd5b6001600160a01b038316600090815260016020526040902054612590908263ffffffff61195016565b6001600160a01b0380851660009081526001602052604080822093909355908416815220546125c5908263ffffffff611de516565b6001600160a01b0380841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60328061262e8339019056fe60806040526040516032380380603283398181016040526020811015602357600080fd5b50516001600160a01b038116fffe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373a934977eb9828ba1f50591af02c98441645b4f0e916e0fecb4cc8e9c633dade2796f752063616e2774207472616e7366657220746f20446973747269627574696f6e20636f6e7472616374796f752063616e2774207472616e7366657220746f2062726964676520636f6e74726163744f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726f6e546f6b656e5472616e7366657228616464726573732c75696e743235362c62797465732963616e277420616464206f6e65206d6f7265206272696467652064756520746f2061206c696d697445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564796f752063616e2774207472616e7366657220746f2041647669736f727352657761726420636f6e7472616374796f752063616e2774207472616e7366657220746f20507269766174654f66666572696e6720636f6e7472616374a265627a7a72305820fbfacd4b36dace16f9fd57104c8aafe8b5a519b29f407207baf7bb6b917422a764736f6c634300050a0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000348448061f604f4adf7ba714460c03cc6eb5b9f4000000000000000000000000348448061f604f4adf7ba714460c03cc6eb5b9f4000000000000000000000000348448061f604f4adf7ba714460c03cc6eb5b9f40000000000000000000000000000000000000000000000000000000000000003717765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037177650000000000000000000000000000000000000000000000000000000000"

        deployed_bytecode =
          "0x608060405234801561001057600080fd5b50600436106102325760003560e01c8063726600ce11610130578063a457c2d7116100b8578063dd62ed3e1161007c578063dd62ed3e1461075f578063f2d5d56b1461078d578063f2fde38b146107b9578063fbb2a53f146107df578063ff9e884d146107e757610232565b8063a457c2d71461069d578063a9059cbb146106c9578063b753a98c146106f5578063bb35783b14610721578063c794c7691461075757610232565b80638f32d59b116100ff5780638f32d59b146105b55780638fcbaf0c146105bd57806395d89b41146106175780639712fdf81461061f5780639da38e2f1461064557610232565b8063726600ce146105595780637a13685a1461057f5780637ecebe00146105875780638da5cb5b146105ad57610232565b806337fb7e21116101be57806354fd4d501161018257806354fd4d50146104ed57806369ffa08a146104f55780636e15d21b1461052357806370a082311461052b578063715018a61461055157610232565b806337fb7e21146103c657806339509351146103ea5780634000aea01461041657806340c10f191461049b5780634bcb88bc146104c757610232565b8063238a3fe111610205578063238a3fe11461033657806323b872dd1461036257806330adf81f14610398578063313ce567146103a05780633644e515146103be57610232565b806304df017d1461023757806306fdde031461025f578063095ea7b3146102dc57806318160ddd1461031c575b600080fd5b61025d6004803603602081101561024d57600080fd5b50356001600160a01b0316610815565b005b610267610a56565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a1578181015183820152602001610289565b50505050905090810190601f1680156102ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610308600480360360408110156102f257600080fd5b506001600160a01b038135169060200135610aec565b604080519115158252519081900360200190f35b610324610b02565b60408051918252519081900360200190f35b6103086004803603604081101561034c57600080fd5b506001600160a01b038135169060200135610b08565b6103086004803603606081101561037857600080fd5b506001600160a01b03813581169160208101359091169060400135610b8d565b610324610baf565b6103a8610bd3565b6040805160ff9092168252519081900360200190f35b610324610bdc565b6103ce610be2565b604080516001600160a01b039092168252519081900360200190f35b6103086004803603604081101561040057600080fd5b506001600160a01b038135169060200135610bf1565b6103086004803603606081101561042c57600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561045c57600080fd5b82018360208201111561046e57600080fd5b8035906020019184600183028401116401000000008311171561049057600080fd5b509092509050610c32565b610308600480360360408110156104b157600080fd5b506001600160a01b038135169060200135610dd2565b6103ce600480360360208110156104dd57600080fd5b50356001600160a01b0316610e80565b610267610e9b565b61025d6004803603604081101561050b57600080fd5b506001600160a01b0381358116916020013516610eb8565b6103ce611083565b6103246004803603602081101561054157600080fd5b50356001600160a01b0316611092565b61025d6110ad565b6103086004803603602081101561056f57600080fd5b50356001600160a01b0316611133565b6103ce61116d565b6103246004803603602081101561059d57600080fd5b50356001600160a01b031661117c565b6103ce61118e565b61030861119d565b61025d60048036036101008110156105d457600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608081013515159060ff60a0820135169060c08101359060e001356111ae565b610267611446565b61025d6004803603602081101561063557600080fd5b50356001600160a01b03166114a7565b61064d6116e6565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610689578181015183820152602001610671565b505050509050019250505060405180910390f35b610308600480360360408110156106b357600080fd5b506001600160a01b03813516906020013561182a565b610308600480360360408110156106df57600080fd5b506001600160a01b038135169060200135611866565b61025d6004803603604081101561070b57600080fd5b506001600160a01b03813516906020013561187d565b61025d6004803603606081101561073757600080fd5b506001600160a01b03813581169160208101359091169060400135611888565b6103ce611899565b6103246004803603604081101561077557600080fd5b506001600160a01b03813581169160200135166118a4565b61025d600480360360408110156107a357600080fd5b506001600160a01b0381351690602001356118cf565b61025d600480360360208110156107cf57600080fd5b50356001600160a01b03166118da565b61032461192d565b610324600480360360408110156107fd57600080fd5b506001600160a01b0381358116916020013516611933565b61081d61119d565b61085c576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b61086581611133565b6108ad576040805162461bcd60e51b8152602060048201526014602482015273189c9a5919d9481a5cdb89dd08195e1a5cdd195960621b604482015290519081900360640190fd5b6001600160a01b038082166000908152600d6020526040812054908290526000805160206126cb833981519152549082169190811680610929576040805162461bcd60e51b81526020600482015260126024820152711e995c9bc81859191c995cdcc8199bdd5b9960721b604482015290519081900360640190fd5b836001600160a01b0316816001600160a01b0316146109c8576001600160a01b038082166000908152600d602052604090205491925090811690811480159061097a57506001600160a01b03811615155b6109c3576040805162461bcd60e51b81526020600482015260156024820152741a5b9d985b1a59081859191c995cdcc8199bdd5b99605a1b604482015290519081900360640190fd5b610929565b6001600160a01b038083166000908152600d602052604080822080548488166001600160a01b0319918216179091559287168252902080549091169055600e54610a1990600163ffffffff61195016565b600e556040516001600160a01b038516907f5d9d5034656cb3ebfb0655057cd7f9b4077a9b42ff42ce223cbac5bc586d212690600090a250505050565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ae25780601f10610ab757610100808354040283529160200191610ae2565b820191906000526020600020905b815481529060010190602001808311610ac557829003601f168201915b5050505050905090565b6000610af93384846119ad565b50600192915050565b60035490565b600a546000906001600160a01b0316331480610b2e5750600b546001600160a01b031633145b80610b435750600c546001600160a01b031633145b610b83576040805162461bcd60e51b815260206004820152600c60248201526b3bb937b7339039b2b73232b960a11b604482015290519081900360640190fd5b610af98383611a99565b6000610b9a848484611bd9565b610ba5848484611c2c565b5060019392505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b60065460ff1690565b60075481565b600a546001600160a01b031681565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610af9918590610c2d908663ffffffff611de516565b6119ad565b6000846001600160a01b03811615801590610c5657506001600160a01b0381163014155b610c9f576040805162461bcd60e51b81526020600482015260156024820152741b9bdd0818481d985b1a59081c9958da5c1a595b9d605a1b604482015290519081900360640190fd5b610ca98686611a99565b856001600160a01b0316336001600160a01b03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1687878760405180848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a3610d37866001600160a01b0316611e46565b15610dc657610d7e33878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e4c92505050565b610dc6576040805162461bcd60e51b815260206004820152601460248201527318dbdb9d1c9858dd0818d85b1b0819985a5b195960621b604482015290519081900360640190fd5b50600195945050505050565b6000610ddd33611133565b610e2e576040805162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206272696467650000000000000000604482015290519081900360640190fd5b610e388383612039565b6040805183815290516001600160a01b038516917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885919081900360200190a250600192915050565b600d602052600090815260409020546001600160a01b031681565b604051806040016040528060018152602001603160f81b81525081565b610ec061119d565b610eff576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b806001600160a01b03811615801590610f2157506001600160a01b0381163014155b610f6a576040805162461bcd60e51b81526020600482015260156024820152741b9bdd0818481d985b1a59081c9958da5c1a595b9d605a1b604482015290519081900360640190fd5b6001600160a01b038316610fe8576040513031906001600160a01b0384169082156108fc029083906000818181858888f19350505050610fe2578083604051610fb290612621565b6001600160a01b039091168152604051908190036020019082f080158015610fde573d6000803e3d6000fd5b5050505b5061107e565b604080516370a0823160e01b8152306004820152905184916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561103357600080fd5b505afa158015611047573d6000803e3d6000fd5b505050506040513d602081101561105d57600080fd5b5051905061107b6001600160a01b038316858363ffffffff61212b16565b50505b505050565b600c546001600160a01b031681565b6001600160a01b031660009081526001602052604090205490565b6110b561119d565b6110f4576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152600f60248201526e1b9bdd081a5b5c1b195b595b9d1959608a1b604482015290519081900360640190fd5b60006001600160a01b038281161480159061116757506001600160a01b038281166000908152600d60205260409020541615155b92915050565b600b546001600160a01b031681565b60086020526000908152604090205481565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b8415806111c25750846111bf61217d565b11155b611204576040805162461bcd60e51b815260206004820152600e60248201526d696e76616c69642065787069727960901b604482015290519081900360640190fd5b600754604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020808301919091526001600160a01b03808d16838501528b166060830152608082018a905260a0820189905287151560c0808401919091528351808403909101815260e08301845280519082012061190160f01b610100840152610102830194909452610122808301949094528251808303909401845261014282018084528451948201949094206000909452610162820180845284905260ff87166101828301526101a282018690526101c2820185905291516001926101e2808401939192601f1981019281900390910190855afa15801561130e573d6000803e3d6000fd5b505050602060405103516001600160a01b0316896001600160a01b03161461137d576040805162461bcd60e51b815260206004820152601f60248201527f696e76616c6964207369676e6174757265206f7220706172616d657465727300604482015290519081900360640190fd5b6001600160a01b038916600090815260086020526040902080546001810190915587146113e1576040805162461bcd60e51b815260206004820152600d60248201526c696e76616c6964206e6f6e636560981b604482015290519081900360640190fd5b6000856113ef5760006113f3565b6000195b90506114008a8a836119ad565b8561140c57600061140e565b865b6001600160a01b039a8b1660009081526009602090815260408083209c909d1682529a909a5299909820989098555050505050505050565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ae25780601f10610ab757610100808354040283529160200191610ae2565b6114af61119d565b6114ee576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b6032600e541061152f5760405162461bcd60e51b81526004018080602001828103825260288152602001806127816028913960400191505060405180910390fd5b611541816001600160a01b0316611e46565b61158b576040805162461bcd60e51b81526020600482015260166024820152756e6f74206120636f6e7472616374206164647265737360501b604482015290519081900360640190fd5b61159481611133565b156115de576040805162461bcd60e51b815260206004820152601560248201527462726964676520616c72656164792065786973747360581b604482015290519081900360640190fd5b6001600160a01b036000819052600d6020526000805160206126cb833981519152541680611653576040805162461bcd60e51b815260206004820152601c60248201527f666972737420627269646765206973207a65726f206164647265737300000000604482015290519081900360640190fd5b600d6020526000805160206126cb83398151915280546001600160a01b03199081166001600160a01b038581169182179093556000908152604090208054909116918316919091179055600e546116ab906001611de5565b600e556040516001600160a01b038316907f3cda433c5679ae4c6a5dea50840e222a42cba3695e4663de4366be899348422190600090a25050565b606080600e54604051908082528060200260200182016040528015611715578160200160208202803883390190505b506001600160a01b036000818152600d6020526000805160206126cb83398151915254929350911680611784576040805162461bcd60e51b81526020600482015260126024820152711e995c9bc81859191c995cdcc8199bdd5b9960721b604482015290519081900360640190fd5b6001600160a01b038181161461182257808383815181106117a157fe5b6001600160a01b039283166020918202929092018101919091529181166000908152600d90925260409091205460019290920191168061181d576040805162461bcd60e51b81526020600482015260126024820152711e995c9bc81859191c995cdcc8199bdd5b9960721b604482015290519081900360640190fd5b611784565b509091505090565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610af9918590610c2d908663ffffffff61195016565b60006118728383611a99565b610af9338484611c2c565b61107e338383610b8d565b611893838383610b8d565b50505050565b6001600160a01b0381565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b61107e823383610b8d565b6118e261119d565b611921576040805162461bcd60e51b8152602060048201819052602482015260008051602061273b833981519152604482015290519081900360640190fd5b61192a81612181565b50565b600e5481565b600960209081526000928352604080842090915290825290205481565b6000828211156119a7576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6001600160a01b0383166119f25760405162461bcd60e51b81526004018080602001828103825260248152602001806127ce6024913960400191505060405180910390fd5b6001600160a01b038216611a375760405162461bcd60e51b81526004018080602001828103825260228152602001806126a96022913960400191505060405180910390fd5b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600a546000906001600160a01b0316331480611abf5750600b546001600160a01b031633145b80611ad45750600c546001600160a01b031633145b15611b885733600090815260016020526040902054611af9908363ffffffff61195016565b33600090815260016020526040808220929092556001600160a01b03851681522054611b2b908363ffffffff611de516565b6001600160a01b0384166000818152600160209081526040918290209390935580518581529051919233927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001611b95565b611b928383612221565b90505b8061107e576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6000611be684848461222e565b905080611893576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b611c3e826001600160a01b0316611e46565b8015611c655750604080516000815260208101909152611c6390849084908490611e4c565b155b1561107e57611c7382611133565b15611caf5760405162461bcd60e51b81526004018080602001828103825260258152602001806127166025913960400191505060405180910390fd5b600a546001600160a01b0383811691161415611cfc5760405162461bcd60e51b815260040180806020018281038252602b8152602001806126eb602b913960400191505060405180910390fd5b600b546001600160a01b0383811691161415611d495760405162461bcd60e51b815260040180806020018281038252602e815260200180612849602e913960400191505060405180910390fd5b600c546001600160a01b0383811691161415611d965760405162461bcd60e51b815260040180806020018281038252602d81526020018061281c602d913960400191505060405180910390fd5b604080516001600160a01b0380861682528416602082015280820183905290517f11249f0fc79fc134a15a10d1da8291b79515bf987e036ced05b9ec119614070b9181900360600190a1505050565b600082820183811015611e3f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b3b151590565b6000606060405180606001604052806026815260200161275b6026913990506000856001600160a01b03168288878760405160240180846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611ed9578181015183820152602001611ec1565b50505050905090810190601f168015611f065780820380516001836020036101000a031916815260200191505b50945050505050604051602081830303815290604052906040518082805190602001908083835b60208310611f4c5780518252601f199092019160209182019101611f2d565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932092860180516001600160e01b03166001600160e01b031990941693909317835251855190945084935090508083835b60208310611fc45780518252601f199092019160209182019101611fa5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612026576040519150601f19603f3d011682016040523d82523d6000602084013e61202b565b606091505b509098975050505050505050565b6001600160a01b038216612094576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6003546120a7908263ffffffff611de516565b6003556001600160a01b0382166000908152600160205260409020546120d3908263ffffffff611de516565b6001600160a01b03831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261107e908490612325565b4290565b6001600160a01b0381166121c65760405162461bcd60e51b81526004018080602001828103825260268152602001806126836026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610af93384846124dd565b600061223b8484846124dd565b6001600160a01b0384163314610ba557600061225785336118a4565b9050600019811461227c576122778533610c2d848763ffffffff61195016565b61231f565b6001600160a01b038516600090815260096020908152604080832033845290915290205415806122d657506122af61217d565b6001600160a01b038616600090815260096020908152604080832033845290915290205410155b61231f576040805162461bcd60e51b8152602060048201526015602482015274195e1c1a5c9e481a5cc81a5b881d1a19481c185cdd605a1b604482015290519081900360640190fd5b50610ba5565b612337826001600160a01b0316611e46565b612388576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106123c65780518252601f1990920191602091820191016123a7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612428576040519150601f19603f3d011682016040523d82523d6000602084013e61242d565b606091505b509150915081612484576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611893578080602001905160208110156124a057600080fd5b50516118935760405162461bcd60e51b815260040180806020018281038252602a8152602001806127f2602a913960400191505060405180910390fd5b6001600160a01b0383166125225760405162461bcd60e51b81526004018080602001828103825260258152602001806127a96025913960400191505060405180910390fd5b6001600160a01b0382166125675760405162461bcd60e51b81526004018080602001828103825260238152602001806126606023913960400191505060405180910390fd5b6001600160a01b038316600090815260016020526040902054612590908263ffffffff61195016565b6001600160a01b0380851660009081526001602052604080822093909355908416815220546125c5908263ffffffff611de516565b6001600160a01b0380841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60328061262e8339019056fe60806040526040516032380380603283398181016040526020811015602357600080fd5b50516001600160a01b038116fffe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373a934977eb9828ba1f50591af02c98441645b4f0e916e0fecb4cc8e9c633dade2796f752063616e2774207472616e7366657220746f20446973747269627574696f6e20636f6e7472616374796f752063616e2774207472616e7366657220746f2062726964676520636f6e74726163744f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726f6e546f6b656e5472616e7366657228616464726573732c75696e743235362c62797465732963616e277420616464206f6e65206d6f7265206272696467652064756520746f2061206c696d697445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564796f752063616e2774207472616e7366657220746f2041647669736f727352657761726420636f6e7472616374796f752063616e2774207472616e7366657220746f20507269766174654f66666572696e6720636f6e7472616374a265627a7a72305820fbfacd4b36dace16f9fd57104c8aafe8b5a519b29f407207baf7bb6b917422a764736f6c634300050a0032"

        contract_address = insert(:contract_address, contract_code: deployed_bytecode)

        input_data = %Data{
          bytes: Base.decode16!(input, case: :lower)
        }

        :transaction
        |> insert(created_contract_address_hash: contract_address.hash, input: input_data)
        |> with_block(status: :ok)

        params = %{
          "contract_source_code" => source_code,
          "compiler_version" => "v0.5.10+commit.5a6ea5b1",
          "evm_version" => "default",
          "name" => "ERC677MultiBridgeToken",
          "optimization" => true,
          "optimization_runs" => @optimization_runs,
          "autodetect_constructor_args" => true
        }

        assert {:ok,
                %{
                  abi: abi,
                  constructor_arguments:
                    "00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000348448061f604f4adf7ba714460c03cc6eb5b9f4000000000000000000000000348448061f604f4adf7ba714460c03cc6eb5b9f4000000000000000000000000348448061f604f4adf7ba714460c03cc6eb5b9f40000000000000000000000000000000000000000000000000000000000000003717765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037177650000000000000000000000000000000000000000000000000000000000"
                }} = Verifier.evaluate_authenticity(contract_address.hash, params)

        assert abi != nil
      end
    end
  end
end
